如何在Python列表中计算连续重复项

12

我有一个列表,只包含 (-1) 和 1:

list1=[-1,-1,1,1,1,-1,1]

我正在尝试将连续重复出现的次数添加到一个列表中,例如:

count_dups=[2,3,1,1] 

我尝试创建一个新列表,并将zip函数用作第一步,但由于截止终值的限制,似乎无法继续操作。

list2=list1[1:]
empty=[]
for x,y in zip(list1,list2):
    if x==y:
        empty.append(x)
    else:
        empty.append(0)

你为什么在这里使用 zip?它似乎与任务无关。 - TigerhawkT3
我认为你应该使用 itertools.groupby - Ozgur Vatansever
请参考这个问题。它有一个传统的实现和一个使用groupby的实现。您应该能够根据自己的需求进行调整。 - user6732794
3个回答

27
您可以使用 itertools.groupby:
from itertools import groupby
list1 = [-1, -1, 1, 1, 1, -1, 1]
count_dups = [sum(1 for _ in group) for _, group in groupby(list1)]
print(count_dups)

输出:

[2, 3, 1, 1]

1
len(list(group)) 在小序列上的速度会更快,但如果您有一个非常大的可迭代对象,并且其中包含大量连续值,则考虑使用 sum(1 for _ in group) 可能更值得。 - Jon Clements
我刚刚在编辑这个程序,使用迭代器而不是强制转换为列表 =D 是的 - 我同意。 - Karin
3
对于新手来说,在sum生成器表达式内部以及列表推导的外部都使用变量名“_”可能会令人困惑,特别是如果他们不熟悉在循环中使用“_”作为一个临时变量的约定时。因此,你可以提醒一下,这里使用的两个“_”是相互独立的。 - PM 2Ring
@PM2Ring,就我个人而言,我会将“_, group”重命名为“_k, group”,因为我经常忘记“groupby()”产生的结果。 - wjandrea

2
def count_dups(L):
    ans = []
    if not L:
        return ans
    running_count = 1
    for i in range(len(L)-1):
        if L[i] == L[i+1]:
            running_count += 1
        else:
            ans.append(running_count)
            running_count = 1
    ans.append(running_count)
    return ans

1
def count_dups(lst):
    return reduce(
        lambda a,b: (((a[-1] == b) and (a[:-2] + [a[-2]+1,a[-1]])) or (a[:-1] + [1,b])) ,
        lst[1:] ,
        [1,lst[0]]
    )[:-1]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接