计算连续Nones的出现长度和连续发生的次数

时间:2017-06-22 14:14:46

标签: python list

我有一个列表r = [1,2,3,None,None,4,None,5]我想知道无出现的次数和长度。这应该给我:

  • [2,1]和2

我写了以下代码:

#!/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中有更好的方法吗?

3 个答案:

答案 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设置为公共组对象;如果kNone,则表示您手头有一系列连续的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]