Counting consecutive numbers in a list

Question:

I couldn’t find a question that was similar enough to mine to where I could develop a satisfactory answer.

I’m pretty new to Python (3.4.3). I am trying to add elements to an output list using a for loop by comparing each element of an input list to the next element in it.

Here is my code so far:

random_list=[1,4,5,6,7,9,19,21,22,23,24]

def count_consec(random_list):
    count=1
    consec_list=[]
    for i in listrand:
        if listrand[i] == listrand[i+1]+1:
            count+=1
        else:
            list.append(count)
    return consec_list

Basically, I want to add to consec_list[] values that represent how the length of consecutive blocks of numbers in random_list[].

I expect my output in this case to look like this:

[1,4,1,1,4]

As in, there is one singular number, followed by 4 consecutive numbers, followed by one singular number, followed by one singular number, followed by 4 consecutive numbers.

I tried many different ways and I have gotten the function to build a list, but all the elements are 1s.

Asked By: Patrick Abeli

||

Answers:

The following code fixes it up. You were iterating over the elements of the list itself instead of the counter you were referencing.

random_list=[1,4,5,6,7,9,19,21,22,23,24]

def count_consec(listrand):
    count=1
    consec_list=[]
    for i in range(len(listrand[:-1])):
        if listrand[i]+1 == listrand[i+1]:
            count+=1
        else:
            consec_list.append(count)
            count=1

    # Account for the last iteration
    consec_list.append(count)     

    return consec_list

print(count_consec(random_list))      

Returns this:

[1, 4, 1, 1, 4]
Answered By: Brian

You could take an approach like this:

def countlist(random_list):
    retlist = []
    # Avoid IndexError for  random_list[i+1]
    for i in range(len(random_list) - 1):
        # Check if the next number is consecutive
        if random_list[i] + 1 == random_list[i+1]:
            count += 1
        else:
            # If it is not append the count and restart counting
            retlist.append(count)
            count = 1
    # Since we stopped the loop one early append the last count
    retlist.append(count)
    return retlist
Answered By: Tristan

There are a few problems with your code, among others undefined variables, or using an element i from the list as the index of that element, but also you will get an index error for the last element, and you never add the last count to the result list.

Instead, I’d suggest using the zip(lst, lst[1:]) recipe for iterating pairs of elements from the list, and using consec[-1] to access and modify the counts already in the list.

def count_consec(lst):
    consec = [1]
    for x, y in zip(lst, lst[1:]):
        if x == y - 1:
            consec[-1] += 1
        else:
            consec.append(1)
    return consec

random_list=[1,4,5,6,7,9,19,21,22,23,24]
print(count_consec(random_list))
# [1, 4, 1, 1, 4]

Alternatively, you could subtract the index from each element. This way, successive consecutive elements will end up being the same element. Now, you can just use itertools.groupby to group and count those elements.

>>> random_list=[1,4,5,6,7,9,19,21,22,23,24]
>>> [e-i for i, e in enumerate(random_list)]
[1, 3, 3, 3, 3, 4, 13, 14, 14, 14, 14]
>>> [sum(1 for _ in g) for _, g in itertools.groupby(_)]
[1, 4, 1, 1, 4]
Answered By: tobias_k

Here’s my version

Say you had a list of numbers, which you want to loop through and count the consecutive streaks:

list_of_nums = [4,5,7,8,2,1,3,5,7,6,8,9,9,9,2,2]

You could do something like this:

streak_count = []
counter = 1
for i in range(len(list_of_nums)):
    if i != (len(list_of_nums) - 1):
        diff = list_of_nums[i+1] - list_of_nums[i]
        if diff == 1:
            counter += 1
        else:
            streak_count.append(counter)
            counter = 1
    else:
        streak_count.append(counter)
Answered By: Baba.S

Here is a more pythonic way of solution,

alist = [1,4,5,6,7,9,19,21,22,23,24]

Before taking the difference, duplicate the first element of the list and add an extra element of which the difference is more than 1 with the last element of the list to the end of the list

alist = np.array([alist[0]] + alist + [alist[-1]+2])

Get the indexes where the differences of consecutive elements in the list are greater than 1

dif1_loc = np.where(np.diff(alist) != 1)[0]
dif1_loc
> [ 0  1  5  6  7 11]

Take the difference of the locations to get the length of each patterns of consecutive numbers

consec_len = np.diff(dif1_loc).values
consec_len
> array([1, 4, 1, 1, 4])
Answered By: ibilgen