Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: determine length of sequence of equal items in list

Tags:

python

list

count

I have a list as follows:

l = [0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,2,2,2]

I want to determine the length of a sequence of equal items, i.e for the given list I want the output to be:

[(0, 6), (1, 6), (0, 4), (2, 3)]

(or a similar format).

I thought about using a defaultdict but it counts the occurrences of each item and accumulates it for the entire list, since I cannot have more than one key '0'.

Right now, my solution looks like this:

out = []
cnt = 0

last_x = l[0]  
for x in l:
    if x == last_x:
        cnt += 1
    else:
        out.append((last_x, cnt))
        cnt = 1
    last_x = x
out.append((last_x, cnt))

print out

I am wondering if there is a more pythonic way of doing this.

like image 620
cschol Avatar asked Oct 19 '10 02:10

cschol


People also ask

How do you find the length of a sequence in Python?

There is a built-in function called len() for getting the total number of items in a list, tuple, arrays, dictionary, etc. The len() method takes an argument where you may provide a list and it returns the length of the given list.

How do you find the length of a sequence?

Suppose we have a sequence. How can we find its length. Well if the sequence is represented by a Python list or a Python tuple object, we can just use the len function.

How do you print the length of each element in a list Python?

To get the length of a list in Python, you can use the built-in len() function. Apart from the len() function, you can also use a for loop and the length_hint() function to get the length of a list. In this article, I will show you how to get the length of a list in 3 different ways.

How do you find the number of elements in a list in Python?

Using Len() function to Get the Number of Elements We can use the len( ) function to return the number of elements present in the list.


2 Answers

You almost surely want to use itertools.groupby:

l = [0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,2,2,2]
answer = []
for key, iter in itertools.groupby(l):
    answer.append((key, len(list(iter))))

# answer is [(0, 6), (1, 6), (0, 4), (2, 3)]

If you want to make it more memory efficient, yet add more complexity, you can add a length function:

def length(l):
    if hasattr(l, '__len__'):
        return len(l)
    else:
        i = 0
        for _ in l:
            i += 1
        return i

l = [0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,2,2,2]
answer = []
for key, iter in itertools.groupby(l):
    answer.append((key, length(iter)))

# answer is [(0, 6), (1, 6), (0, 4), (2, 3)]

Note though that I have not benchmarked the length() function, and it's quite possible it will slow you down.

like image 125
Mike Axiak Avatar answered Sep 25 '22 12:09

Mike Axiak


Mike's answer is good, but the itertools._grouper returned by groupby will never have a __len__ method so there is no point testing for it

I use sum(1 for _ in i) to get the length of the itertools._grouper

>>> import itertools as it
>>> L = [0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,2,2,2]
>>> [(k, sum(1 for _ in i)) for k, i in it.groupby(L)]
[(0, 6), (1, 6), (0, 4), (2, 3)]
like image 44
John La Rooy Avatar answered Sep 24 '22 12:09

John La Rooy