从列表中删除类似项目的pythonic方法

时间:2014-01-08 12:41:45

标签: python itertools

我有一个项目列表,我想要删除所有类似的值,但第一个和最后一个。例如:

listIn = [1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1]
  1. 前三个元素“1,1,1”相似,所以删除中间的“1”。
  2. 接下来两个零未经修改。
  3. 一个只是一个。保持不变。
  4. 四个零。删除第一个和最后一个之间的项目。
  5. 导致:

    listOut = [1, 1, 0, 0, 1, 0, 0, 1]
    

    在c ++中这样做的方式非常明显,但它看起来与python编码风格截然不同。或者这是唯一的方式?

    基本上,只需删除图表中过多的点,其中“y”值不会改变: enter image description here

3 个答案:

答案 0 :(得分:6)

使用itertools.groupby()对您的值进行分组:

from itertools import groupby

listOut = []
for value, group in groupby(listIn):
    listOut.append(next(group))
    for i in group:
        listOut.append(i)
        break

或者,为了提高效率,作为发电机:

from itertools import groupby

def reduced(it):
    for value, group in groupby(it):
        yield next(group)
        for i in group:
            yield i
            break

演示:

>>> listIn = [1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1]
>>> list(reduced(listIn))
[1, 1, 0, 0, 1, 0, 0, 1]

答案 1 :(得分:1)

一衬垫:

listOut = reduce(lambda x, y: x if x[-1] == y and x[-2] == y else x + [y], listIn, listIn[0:2])

答案 2 :(得分:1)

这为问题提供了一个小小的解决方案;对于大型数组而言,它应该比基于itertools的数组快得多。可以说,如果你正在进行任何类型的信号处理,有充分的理由使用numpy。

import numpy as np
a = np.array([1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1], np.int)

change = a[:-1] != a[1:]
I = np.zeros_like(a, np.bool)
I[:-1] = change
I[1:] += change
print a[I]