Reputation: 803
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
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
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
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
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