在列表中识别连续重复项的最Pythonic方法是什么?

mac*_*ing 28 python list generator duplicates

我有一个整数列表,我希望能够识别连续的重复块:也就是说,我想生成一个保留顺序的双重列表,其中每个双重包含(int_in_question,出现次数).

例如,如果我有一个列表,如:

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

我希望结果如下:

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

我有一个相当简单的方法,使用for循环,temp和计数器:

result_list = []
current = source_list[0]
count = 0
for value in source_list:
    if value == current:
        count += 1
    else:
        result_list.append((current, count))
        current = value
        count = 1
result_list.append((current, count))
Run Code Online (Sandbox Code Playgroud)

但我真的很喜欢python的函数式编程习语,我希望能够通过一个简单的生成器表达式来实现这一点.但是我发现在使用发电机时很难保留子计数.我有一种感觉,两个步骤可能会让我在那里,但是现在我很难过.

是否有一种特别优雅/ pythonic的方式来做到这一点,特别是对于发电机?

Jos*_*ell 50

>>> from itertools import groupby
>>> L = [0, 0, 0, 3, 3, 2, 5, 2, 6, 6]
>>> grouped_L = [(k, sum(1 for i in g)) for k,g in groupby(L)]
>>> # Or (k, len(list(g))), but that creates an intermediate list
>>> grouped_L
[(0, 3), (3, 2), (2, 1), (5, 1), (2, 1), (6, 2)]
Run Code Online (Sandbox Code Playgroud)

正如他们所说,包括电池.

建议sumJBernardo 使用和生成表达式; 看评论.

  • +1,也许你可以改变`len(list(g))`for sum(1 for i in g)`以避免中间存储. (10认同)
  • @JBernardo:好建议,谢谢。当我使用“groupby”时,从“g”创建列表总是让我感到困扰。 (2认同)
  • @machine:这原则上是不可能的.考虑:`def long_gen():while True:yield 1`这个`len`是什么?请参阅:http://stackoverflow.com/questions/390852/is-there-any-built-in-way-to-get-the-length-of-an-iterable-in-python (2认同)