简体   繁体   中英

Consecutive repeated identical elements

I have a list that will consist of 1s and 0s. An example is: [1,1,1,1,1,0,1,0,1,0,0,0,0,0,1,1,1] I am trying to print the number of times there were consecutive 1s. The desired output is 2. What I have so far:

def span(test_list):
    res = []
    for idx in range(0, len(test_list) - 1):
      
    # getting Consecutive elements 
        if test_list[idx] == test_list[idx + 1]:
            if test_list[idx]!=0:
                res.append(test_list[idx])
          
# getting count of unique elements        
    res = len(list(set(res)))
  
# printing result 
    print("Consecutive identical elements count : " + str(res))
        

This however returns 1, where as I need the answer to be 2. Any help will be appreciated.

Just for fun... a solution using itertools.groupby :

test_list = [1,1,1,1,1,0,1,0,1,0,0,0,0,0,1,1,1]
sum(g[0] == 1 and len(g) > 1 for g in [list(g) for _, g in groupby(test_list)])

Output:

2

This works by grouping the consecutive identical values in the list which yields:

[1, 1, 1, 1, 1]
[0]
[1]
[0]
[1]
[0, 0, 0, 0, 0]
[1, 1, 1]

We then sum all the cases where the first element in the group is 1 and the length of the group is > 1.

@JonClements came up with an interesting way of doing this using itertools.islice which avoids the list conversion:

sum(next(islice(g, 1, None), 0) for k, g in groupby(test_list))

This works by taking a slice of the resultant group starting at the second element ( islice(g, 1, None) ) and then attempts to read that element ( next(..., 0) ) returning 0 if there isn't one. Thus next(islice(g, 1, None), 0) will only return 1 if the group is at least two 1 's long.

Inspired by @JonClements' comment, I also came up with:

sum(next(g) & next(g, 0) for _, g in groupby(test_list))

This works by bitwise and'ing the first and second (or 0 if there isn't a second) elements in each grouped list, so only produces a 1 value if the grouped list contains more than one 1 .

Timing wise, on my computer this is the fastest solution, with @JonClements about 20% slower and my original solution another 20% slower again.

Your problem here is that you are trying to add to your result list the sequences of consecutive ones, but there will be nothing to separate and distinguish the different sequences. So your result will look something like this:

[1,1,1,1,1,1]

Which will be reduce to just 1 when you convert it to a set. My proposition is to track only the beginning of each consecutive sequence of ones, and to sum it like this:

def span(test_list):
    res = []
    started = False

    for idx in range(0, len(test_list) - 1):
  

        if test_list[idx] == test_list[idx + 1]:
            if test_list[idx]!=0 and not started:
                started = True
                res.append(test_list[idx])

        else:
            started = False
            

    res = sum(res)

    print("Consecutive identical elements count : " + str(res))

test_liste = [1,1,1,1,1,0,1,0,1,0,0,0,0,0,1,1,1]

span(test_liste)

Why don't you use a counter that you increment each time list(n+1) == list(n)? It will be easier than having to add each time an element to a list and then at the end to get the length of your list.

Apart from that, the problem you have is a logic problem. When you check that element n+1 is similar to your element n and that your element n is 1, you add only one element to your list (initially empty) while you checked that you had two similar elements.

My advice is to first check that the first element you read is a 1. If it is not, then you go to the next one. If it is, then you increment your counter by 1 and check the next one. If the next one is 1 then you increment your counter by 1. And so on.

What about it? :

def span(test_list):
    res = 0
    for idx in range(0, len(test_list) - 1):
       # check that you have two consecutive 1
       if test_list[idx] == 1 and test_list[idx + 1] == 1:
        res += 1;

        # As long as the following values are 1, idx is incremented without incrementing res
        while test_list[idx +1] == 1: //
          idx += 1;
    print("Consecutive identical elements count : " + str(res))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM