我有一个列表r = [1,2,3,None,None,4,None,5]
我想知道无出现的次数和长度。这应该给我:
我写了以下代码:
#!/usr/bin/env python
def compute_stats():
r = [1,2,3,None,None,4,None,5]
length = []
counter = 0
i = 0
while i < len(r):
if r[i] == None:
j = i
l = 0
while j < len(r) and r[j] == None:
l += 1
j += 1
length.append(l)
counter+= 1
i = j + 1
else:
i += 1
print str(r) +" length: " + str(length) +" counter " + str(counter)
if __name__ == "__main__":
compute_stats()
作为输出我得到以下
[1, 2, 3, None, None, 4, None, 5] length: [2, 1] counter 2
代码很好用。但是在python中有更好的方法吗?
答案 0 :(得分:2)
使用itertools.groupby()
object对连续的None
值进行分组,并计算群组长度:
[sum(1 for _ in g) for k, g in groupby(input) if k is None]
由于g
是未知长度的迭代器,我使用sum()
来避免将其实现为列表;否则可能会非常耗费内存。如果您100%确定您的连续None
个对象组很小(最多只有几百个),那么只需使用len(list(g))
就可以 更快。
groupby()
的默认行为是生成相同对象的组,因此is
测试为真的连续对象。这非常适合None
值。对于每个组,生成k
和依赖迭代器,并将k
设置为公共组对象;如果k
为None
,则表示您手头有一系列连续的None
个对象。
答案 1 :(得分:1)
使用itertools.groupby
对连续的相似项目进行分组,并过滤掉组密钥为not None
的项目:
from itertools import groupby
lst = [1,2,3,None,None,4,None,5]
cnt = [len(list(g)) for k, g in groupby(lst) if k is None]
print(cnt, len(cnt))
# [2, 1], 2
答案 2 :(得分:1)
from itertools import groupby
r = [1,2,3,None,None,4,None,5]
[len(list(g)) for k, g in groupby(r) if k is None]