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

csc*_*hol 7 python list count

我有一个列表如下:

l = [0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,2,2,2]
Run Code Online (Sandbox Code Playgroud)

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

[(0, 6), (1, 6), (0, 4), (2, 3)]
Run Code Online (Sandbox Code Playgroud)

(或类似的格式).

我想过使用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
Run Code Online (Sandbox Code Playgroud)

我想知道是否有更多的pythonic方式这样做.

Mik*_*iak 14

你几乎肯定想使用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)]
Run Code Online (Sandbox Code Playgroud)

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

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)]
Run Code Online (Sandbox Code Playgroud)

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