Python:确定列表中相等项的序列长度

7 投票
2 回答
3942 浏览
提问于 2025-04-16 05:43

我有一个这样的列表:

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

我在想有没有更符合 Python 风格的方法来做到这一点。

2 个回答

4

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)]
16

你几乎肯定想要使用 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)]

不过要注意,我没有测试这个长度函数的速度,可能会让你的程序变慢。

撰写回答