【问题标题】:Python: determine length of sequence of equal items in listPython:确定列表中相等项目序列的长度
【发布时间】:2010-10-19 02:44:47
【问题描述】:

我有一个清单如下:

l = [0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,2,2,2]

我想确定一系列相等项目的长度,即对于给定的列表,我希望输出为:

[(0, 6), (1, 6), (0, 4), (2, 3)]

(或类似格式)。

我考虑过使用defaultdict,但它会计算每个项目的出现次数并将其累积到整个列表中,因为我不能有多个键“0”。

现在,我的解决方案如下所示:

out = []
cnt = 0

last_x = l[0]  
for x in l:
    if x == last_x:
        cnt += 1
    else:
        out.append((last_x, cnt))
        cnt = 1
    last_x = x
out.append((last_x, cnt))

print out

我想知道是否有更 Pythonic 的方式来做到这一点。

【问题讨论】:

    标签: python list count


    【解决方案1】:

    您几乎肯定想使用itertools.groupby

    l = [0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,2,2,2]
    answer = []
    for key, iter in itertools.groupby(l):
        answer.append((key, len(list(iter))))
    
    # answer is [(0, 6), (1, 6), (0, 4), (2, 3)]
    

    如果你想提高内存效率,但增加更多复杂性,你可以添加一个长度函数:

    def length(l):
        if hasattr(l, '__len__'):
            return len(l)
        else:
            i = 0
            for _ in l:
                i += 1
            return i
    
    l = [0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,2,2,2]
    answer = []
    for key, iter in itertools.groupby(l):
        answer.append((key, length(iter)))
    
    # answer is [(0, 6), (1, 6), (0, 4), (2, 3)]
    

    请注意,虽然我没有对 length() 函数进行基准测试,但它很可能会减慢您的速度。

    【讨论】:

    • 您可以通过用以下两行替换显示的内容来加快else: 子句的速度:for i,_ in enumerate(l,1): pass 后跟return i
    【解决方案2】:

    Mike 的回答很好,但是 groupby 返回的 itertools._grouper 永远不会有 __len__ 方法,所以没有必要测试它

    我使用sum(1 for _ in i) 来获取itertools._grouper 的长度

    >>> import itertools as it
    >>> L = [0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,2,2,2]
    >>> [(k, sum(1 for _ in i)) for k, i in it.groupby(L)]
    [(0, 6), (1, 6), (0, 4), (2, 3)]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多