例如,如果我有列表
a = [1,1,1,2,2]
b = [1,1,2,2,2]
c = [2,1,1,1,1]
我想获得列表中第一个元素的最长条纹,所以例如a
将给出3,b
将给出2而c
将给出1.我知道我可以创建一个while循环并以这种方式计算条纹,但我想知道是否有更优雅的方法来做到这一点?
答案 0 :(得分:6)
numStreak = ([a[0] == n for n in a]+[False]).index(False)
(这也确保如果所有元素都像第一个元素一样,索引会返回正确的值)
更新:更高效(但不太优雅?)版本
from itertools import takewhile
len([1 for _ in takewhile(lambda x:x==a[0], a)])
或更好一点(更新2)@ vaultah的建议:
sum(1 for _ in takewhile(lambda x:x==a[0], a))
答案 1 :(得分:3)
您可以使用groupby并汇总第一组中每个项目的数量:
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]))
或者使用takewhile:
from itertools import takewhile
for l in [a, b, c]:
print(sum((1 for _ in takewhile(lambda x: x == l[0], l))))
如果您的数据始终是 groupby 中的列表,元组等..您可以检查 falsey 值,而不是在{{1}中设置默认值}:
next(..
答案 2 :(得分:1)
一条公路班轮?瞄准......
a = [5,5,5,5,8]
list(np.ediff1d(a)).count(0)+1
>>> 4
答案 3 :(得分:0)
你可以使用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])]
然后只需要第一次运行的长度:
>>> for e in a,b,c:
... len(runs(np.array(e))[0])
...
3
2
1
或者,在Python中,只需使用while
循环:
>>> def r(a):
... i=1
... while a[0]==a[i]: i+=1
... return i
...
>>> r(a)
3
>>> r(b)
2
>>> r(c)
1