删除在Python中具有连续重复项的元素

时间:2011-04-21 02:39:14

标签: python list duplicates

我对这个问题感到好奇:Eliminate consecutive duplicates of list elements,以及如何在Python中实现它。

我想出的是:

list = [1,1,1,1,1,1,2,3,4,4,5,1,2]
i = 0

while i < len(list)-1:
    if list[i] == list[i+1]:
        del list[i]
    else:
        i = i+1

输出:

[1, 2, 3, 4, 5, 1, 2]

我猜是好的。

所以我很好奇,想知道我是否可以删除连续重复的元素并获得此输出:

[2, 3, 5, 1, 2]

为此我做了这个:

list = [1,1,1,1,1,1,2,3,4,4,5,1,2]
i = 0
dupe = False

while i < len(list)-1:
    if list[i] == list[i+1]:
        del list[i]
        dupe = True
    elif dupe:
        del list[i]
        dupe = False
    else:
        i += 1

但它似乎有点笨拙而不是pythonic,你有更聪明/更优雅/更有效的方式来实现它吗?

9 个答案:

答案 0 :(得分:48)

>>> L = [1,1,1,1,1,1,2,3,4,4,5,1,2]
>>> from itertools import groupby
>>> [x[0] for x in groupby(L)]
[1, 2, 3, 4, 5, 1, 2]

如果您愿意,可以使用地图而不是列表理解

>>> from operator import itemgetter
>>> map(itemgetter(0), groupby(L))
[1, 2, 3, 4, 5, 1, 2]

第二部分

>>> [x for x, y in groupby(L) if len(list(y)) < 2]
[2, 3, 5, 1, 2]

如果你不想创建临时列表来获取长度,你可以在生成器表达式上使用sum

>>> [x for x, y in groupby(L) if sum(1 for i in y) < 2]
[2, 3, 5, 1, 2]

答案 1 :(得分:14)

纯Python中的Oneliner

[v for i, v in enumerate(your_list) if i == 0 or v != your_list[i-1]]

答案 2 :(得分:5)

如果您使用Python 3.8+,则可以使用赋值表达式:=

list1 = [1, 2, 3, 3, 4, 3, 5, 5]

prev = object()
list1 = [prev:=v for v in list1 if prev!=v]

print(list1)

打印:

[1, 2, 3, 4, 3, 5]

答案 3 :(得分:2)

一种“懒惰”的方法是使用itertools.groupby

import itertools

list1 = [1, 2, 3, 3, 4, 3, 5, 5]
list1 = [g for g, _ in itertools.groupby(list1)]
print(list1)

输出

[1, 2, 3, 4, 3, 5]

答案 4 :(得分:2)

您可以使用zip_longest() +列表理解来做到这一点。

from itertools import zip_longest 
list1 = [1, 2, 3, 3, 4, 3, 5, 5].
     # using zip_longest()+ list comprehension       
     res = [i for i, j in zip_longest(list1, list1[1:]) 
                                                            if i != j] 
        print ("List after removing consecutive duplicates : " +  str(res)) 

答案 5 :(得分:1)

这是不依赖外部软件包的解决方案:

list = [1,1,1,1,1,1,2,3,4,4,5,1,2] 
L = list + [999]  # append a unique dummy element to properly handle -1 index
[l for i, l in enumerate(L) if l != L[i - 1]][:-1] # drop the dummy element

然后我注意到Ulf Aslak的类似解决方案更干净:)

答案 6 :(得分:1)

上面有很多更好/更多的python答案,但是也可以使用list.pop()完成此任务:

my_list = [1, 2, 3, 3, 4, 3, 5, 5]
for x in my_list[:-1]:
    next_index = my_list.index(x) + 1
    if my_list[next_index] == x:
        my_list.pop(next_index)

输出

[1, 2, 3, 4, 3, 5]

答案 7 :(得分:0)

消除列表元素的连续重复;作为替代方案,您可以将itertools.izip_longest()列表理解一起使用:

>>> from itertools import izip_longest

>>> my_list = [1,1,1,1,1,1,2,3,4,4,5,1,2]
>>> [i for i, j in izip_longest(my_list, my_list[1:]) if i!=j]
[1, 2, 3, 4, 5, 1, 2]

答案 8 :(得分:0)

使用functools.reduce(不包括导入)的另一种可能的方式-字符串和列表的缺点是实现方式略有不同:

>>> from functools import reduce

>>> reduce(lambda a, b: a if a[-1:] == [b] else a + [b], [1,1,2,3,4,4,5,1,2], [])
[1, 2, 3, 4, 5, 1, 2]

>>> reduce(lambda a, b: a if a[-1:] == b else a+b, 'aa  bbb cc')
'a b c'