Count occurrences of elements in a list until a different element appears

Alexandre Mondaini :

Given a list :

lst = [1,1,1,5,3,3,9,3,3,3,3,3]

I want to count the occurrences of each item in the list as they appear in the list so for instance the number 3 in this case will be count two times when 3 is between 5 and 9 it will have a count of 2 and when 3 is after 9 it will have a count of 5. The resulting list should be the item followed by its count.

result = [1,3,5,1,3,2,9,1,3,5]

I've tried the following code but it results in a sort of expanded answer.

lst = [1,1,1,5,3,3,9,3,3,3,3,3]

def myfun(arr):
    for i in arr:
        yield i
        yield arr.count(i)

print(list(myfun(lst)))


[1, 3, 1, 3, 1, 3, 5, 1, 3, 7, 3, 7, 9, 1, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7]
Mark Meyer :

itertools.groupby() is good for this. It will group the items by a key and return and iterator with the key, grouper containing items. You can convert the gouper to a list and take it's length:

from itertools import groupby

lst = [1,1,1,5,3,3,9,3,3,3,3,3]

def counts(lst):
    for k, v in groupby(lst):
        yield k
        yield len(list(v))

list(counts(lst))
# [1, 3, 5, 1, 3, 2, 9, 1, 3, 5]

You can do it as a one-liner with chain too:

from itertools import groupby, chain

lst = [1,1,1,5,3,3,9,3,3,3,3,3]

list(chain.from_iterable((k, len(list(v))) for k, v in groupby(lst)))
# [1, 3, 5, 1, 3, 2, 9, 1, 3, 5]

If, for some reason, you want to do this the hard way, you need to keep track of the current count and the current thing you are counting and append when that thing changes:

lst = [1,1,1,5,3,3,9,3,3,3,3,3]

def makeCounts(lst):
    if len(lst) == 0: 
        return lst
    res = []
    # take first element
    cur = lst[0]
    count = 1

    for n in lst[1:]:
        if n == cur:
            # same item — increase count
            count += 1
        else:
            # new item — reset count and save previous
            res.extend([cur, count])
            count = 1
            cur = n

    # don't forget last item
    res.extend([cur, count])

    return res

makeCounts(lst)
# [1, 3, 5, 1, 3, 2, 9, 1, 3, 5]

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=194141&siteId=1