list - python从一个列表维护顺序如何删除重复?

  显示原文与译文双语对照的内容

是否有一个内置的从 python 中删除重复项,同时保留顺序? 我知道我可以使用一个集合来删除重复项,但这破坏了原始顺序。 我也知道我可以像这样滚动自己的:


def uniq(input):
 output = []
 for x in input:
 if x not in output:
 output.append(x)
 return output

于那相关代码示例 。), ( 感谢放松

但如果可能的话,我想使用内置或者更多的Pythonic 习惯用法。

相关问题: python,什么是最快的算法中用于从列表中删除重复项,以便所有元素只是,同时保留顺序

时间:

在 python 2.7+ 中,接受的常用习惯用法使用 collections.OrderedDict:

运行时:O(N)


>>> from collections import OrderedDict
>>> items = [1, 2, 0, 1, 3, 2]
>>> list(OrderedDict.fromkeys(items))
[1, 2, 0, 3]

这看起来比:


seen = set()
[x for x in seq if x not in seen and not seen.add(x)]

,未能利用丑陋的哈克:

 
not seen.add(x)

 

这取决于 set.add 是一个in-place方法,它总是返回 None,所以 not None 计算为 True

请注意,尽管 hack 解决方案具有相同的运行时复杂度 O(N),但它的速度更快。


sequence = ['1', '2', '3', '3', '6', '4', '5', '6']
unique = []
[unique.append(item) for item in sequence if item not in unique]

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


from itertools import groupby
[ key for key,_ in groupby(sortedList)]

列表甚至不必是排序的,充分的条件是相等的值组合在一起。

:我假设"保留顺序"表示列表实际上是有序的。 如果不是这样,那么来自MizardX的解决方案就是正确的。

社区编辑:这是最优雅的"将重复的连续元素压缩为单个元素"方式。

我想如果你想保持秩序

你可以试试这个:


list1 = ['b','c','d','b','c','a','a'] 
list2 = list(set(list1)) 
list2.sort(key=list1.index) 
print list2

或者,你也可以这样做:


list1 = ['b','c','d','b','c','a','a'] 
list2 = sorted(set(list1),key=list1.index) 
print list2 

你也可以这样做:


list1 = ['b','c','d','b','c','a','a'] 
list2 = [] 
for i in list1: 
 if not i in list2: 
 list2.append(i)` 
print list2

它也可以写成:


list1 = ['b','c','d','b','c','a','a'] 
list2 = [] 
[list2.append(i) for i in list1 if not i in list2] 
print list2 

对于没有hashable类型( 例如。 列表列表,基于:MizardX


def f7_noHash(seq)
 seen = set()
 return [ x for x in seq if str( x ) not in seen and not seen.add( str( x ) )]

这很快但是。。

 
l = list(set(l))

 

如果你的列表项不是 hashable,它将不起作用。

更通用的方法是:


l = reduce(lambda x, y: x if y in x else x + [y], l, [])

它应该适用于所有情况。

MizardX的回答提供了多种方法的好集合。

这就是我在思考时想到的:


mylist = [x for i,x in enumerate(mylist) if x not in mylist[i+1:]]

...