user5368737
user5368737

Reputation: 803

Find number of consecutive elements that are the same before they change

So for example if I have the lists

a = [1,1,1,2,2]
b = [1,1,2,2,2]
c = [2,1,1,1,1]

I would want to get the longest streak of the first element in the list, so for example a would give 3, b would give 2 and c would give 1. I know I could create a while loop and count the streak that way, but I was wondering if there's a more elegant way to do this?

Upvotes: 5

Views: 1045

Answers (4)

dawg
dawg

Reputation: 103754

You could use numpy:

>>> import numpy as np
>>> a = [1,1,1,2,2]
>>> b = [1,1,2,2,2]
>>> c = [2,1,1,1,1]
>>> def runs(data):
...    return np.split(data, np.where(np.diff(data) != 0)[0]+1)
... 
>>> for e in a,b,c:
...    runs(np.array(e))
... 
[array([1, 1, 1]), array([2, 2])]
[array([1, 1]), array([2, 2, 2])]
[array([2]), array([1, 1, 1, 1])]

Then just take the length of the first run:

>>> for e in a,b,c:
...    len(runs(np.array(e))[0])
... 
3
2
1

Or, in Python, just use a while loop:

>>> def r(a):
...    i=1
...    while a[0]==a[i]: i+=1
...    return i
... 
>>> r(a)
3
>>> r(b)
2
>>> r(c)
1

Upvotes: 0

DomTomCat
DomTomCat

Reputation: 8569

you could do something like this:

numStreak = ([a[0] == n for n in a]+[False]).index(False)

(this also makes sure that if all elements are like the first element, index does return the correct value)

UPDATE: a more efficient (but less elegant?) version

from itertools import takewhile
len([1 for _ in takewhile(lambda x:x==a[0], a)])

or a bit better (UPDATE 2) @vaultah's suggestion:

sum(1 for _ in takewhile(lambda x:x==a[0], a))

Upvotes: 6

ajsp
ajsp

Reputation: 2670

One liner for the road? Take aim...

a = [5,5,5,5,8]
list(np.ediff1d(a)).count(0)+1
>>> 4

Upvotes: 1

Padraic Cunningham
Padraic Cunningham

Reputation: 180391

You can use groupby and sum how many items are in the first group for each:

a = [1,1,1,2,2]
b = [1,1,2,2,2]
c = [2,1,1,1,1]

from itertools import groupby

for l in [a,b,c]:
    print(sum( 1  for _ in next(groupby(l), [[], []],)[1]))

Or using takewhile:

from itertools import takewhile

for l in [a, b, c]:
     print(sum((1 for _ in takewhile(lambda x: x == l[0], l))))

If your data is always a list, tuple etc.. in the groupby you can check for a falsey value as opposed to setting a default in next(..:

for l in [a, b, c]:
    print(sum(1 for _ in next(groupby(l))[1]) if l else 0)

Upvotes: 3

Related Questions