删除列表中的重复项

几乎我需要编写一个程序来检查一个列表是否有任何重复,如果它删除它们,并返回一个新的列表与werent复制/删除的项目。 这是我的,但说实话,我不知道该怎么办。

def remove_duplicates(): t = ['a', 'b', 'c', 'd'] t2 = ['a', 'c', 'd'] for t in t2: t.append(t.remove()) return t 

获得一个独特的项目集合的通用方法是使用一个set 。 集合是不同对象的无序集合。 要从任何迭代中创build一个集合,只需将其传递给内置的set()函数即可。 如果您以后需要一个真正的列表,您可以同样将该集合传递给list()函数。

以下示例应该涵盖您正在尝试执行的任何操作:

 >>> t = [1, 2, 3, 1, 2, 5, 6, 7, 8] >>> t [1, 2, 3, 1, 2, 5, 6, 7, 8] >>> list(set(t)) [1, 2, 3, 5, 6, 7, 8] >>> s = [1, 2, 3] >>> list(set(t) - set(s)) [8, 5, 6, 7] 

从示例结果中可以看出,原始订单不被维护。 如上所述,集合本身是无序的集合,所以订单就会丢失。 将一个集合转换回列表时,将创build一个任意的顺序。

如果订单对您很重要,那么您将不得不使用不同的机制。 这个问题更详细地涵盖了这个话题。

FWIW,新的(v2.7)Python方法,用于从迭代中移除重复项,同时保持原始顺序:

 >>> from collections import OrderedDict >>> list(OrderedDict.fromkeys('abracadabra')) ['a', 'b', 'r', 'c', 'd'] 

在Python 3.5中,OrderedDict有一个C实现。 我的时间表明,现在这是各种方法中最快和最短的。

在CPython 3.6中,现在的常规字典既有序又紧凑。 目前,这被认为是一个实施细节,但将来可能成为一个有保证的特征。 这为我们提供了一个新的最快捷的方式来保留顺序:

 >>> list(dict.fromkeys('abracadabra')) ['a', 'b', 'r', 'c', 'd'] 

这是一个list(set(source_list))list(set(source_list))将做的伎俩。

set是不可能有重复的东西。

更新:保留订单的方法是两行:

 from collections import OrderedDict OrderedDict((x, True) for x in source_list).keys() 

这里我们使用OrderedDict记住键的插入顺序的事实,并且在特定键的值被更新时不改变它。 我们插入True作为值,但是我们可以插入任何东西,值不被使用。 ( set工作很像一个被忽略的dict也是。)

 >>> t = [1, 2, 3, 1, 2, 5, 6, 7, 8] >>> t [1, 2, 3, 1, 2, 5, 6, 7, 8] >>> s = [] >>> for i in t: if i not in s: s.append(i) >>> s [1, 2, 3, 5, 6, 7, 8] 

如果你不关心订单,只需要这样做:

 def remove_duplicates(l): return list(set(l)) 

set保证不会有重复。

制作一个新的列表,保留L中第一个重复元素的顺序

newlist=[ii for n,ii in enumerate(L) if ii not in L[:n]]

例如if L=[1, 2, 2, 3, 4, 2, 4, 3, 5] [1,2,3,4,5] if L=[1, 2, 2, 3, 4, 2, 4, 3, 5]newlist将是[1,2,3,4,5]

这将检查每个新元素在添加之前是否先前没有出现在列表中。 也不需要import。

另一种方法是:

 >>> seq = [1,2,3,'a', 'a', 1,2] >> dict.fromkeys(seq).keys() ['a', 1, 2, 3] 

一位同事已经把接受的答案作为他的代码的一部分发给了我今天的codereview。 虽然我当然很欣赏这个答案的优雅,但我对这个表演并不满意。 我试过这个解决scheme(我使用set来减less查找时间)

 def ordered_set(in_list): out_list = [] added = set() for val in in_list: if not val in added: out_list.append(val) added.add(val) return out_list 

为了比较效率,我使用了100个整数的随机样本 – 62个是唯一的

 from random import randint x = [randint(0,100) for _ in xrange(100)] In [131]: len(set(x)) Out[131]: 62 

这里是测量的结果

 In [129]: %timeit list(OrderedDict.fromkeys(x)) 10000 loops, best of 3: 86.4 us per loop In [130]: %timeit ordered_set(x) 100000 loops, best of 3: 15.1 us per loop 

那么,如果设置从解决scheme中删除,会发生什么?

 def ordered_set(inlist): out_list = [] for val in inlist: if not val in out_list: out_list.append(val) return out_list 

结果并不像OrderedDict那样糟糕,但仍然是原来解决scheme的3倍以上

 In [136]: %timeit ordered_set(x) 10000 loops, best of 3: 52.6 us per loop 

我在列表中有一个字典,所以我不能使用上面的方法。 我得到了错误:

 TypeError: unhashable type: 

所以,如果你关心订单和/或一些项目是不可能的 。 那么你可能会觉得这很有用:

 def make_unique(original_list): unique_list = [] [unique_list.append(obj) for obj in original_list if obj not in unique_list] return unique_list 

有些人可能会考虑带有副作用的列表理解不是一个好的解决scheme。 这是一个替代scheme:

 def make_unique(original_list): unique_list = [] map(lambda x: unique_list.append(x) if (x not in unique_list) else False, original_list) return unique_list 

简单和容易:

 myList = [1, 2, 3, 1, 2, 5, 6, 7, 8] cleanlist = [] [cleanlist.append(x) for x in myList if x not in cleanlist] 

输出:

 >>> cleanlist [1, 2, 3, 5, 6, 7, 8] 

尝试使用集合:

 import sets t = sets.Set(['a', 'b', 'c', 'd']) t1 = sets.Set(['a', 'b', 'c']) print t | t1 print t - t1 

你可以使用numpy函数unique()(如果你不想要一个numpy数组,最终使用函数.tolist())

 import numpy as np t=['a','a','b','b','b','c','c','c'] a=np.unique(t).tolist() print a >>>['a','b','c'] 

你也可以这样做:

 >>> t = [1, 2, 3, 3, 2, 4, 5, 6] >>> s = [x for i, x in enumerate(t) if i == t.index(x)] >>> s [1, 2, 3, 4, 5, 6] 

以上原因是因为index方法只返回一个元素的第一个索引。 重复的元素有更高的指数。 参考这里 :

list.index(x [,start [,end]])
在值为x的第一个项目的列表中返回从零开始的索引。 如果没有这样的项目,则引发ValueError。

下面的代码很简单,用于删除列表中的重复

 def remove_duplicates(x): a = [] for i in x: if i not in a: a.append(i) return a print remove_duplicates([1,2,2,3,3,4]) 

它返回[1,2,3,4]

这个关心顺序没有太多的麻烦(OrderdDict&others)。 也许不是最Pythonic的方式,也不是最短的方式,但诀窍:

 def remove_duplicates(list): ''' Removes duplicate items from a list ''' singles_list = [] for element in list: if element not in singles_list: singles_list.append(element) return singles_list 

我在这里看到的所有的顺序保留方法或者使用简单的比较(至多具有O(n ^ 2)时间复杂度)或者重量级的OrderedDicts / set + list组合,这些组合被限制于可哈希input。 这里是一个哈希无关的O(nlogn)解决scheme:

 def filter_duplicates(lst): # Enumerate the list to restore order lately; reduce the sorted list; restore order def append_unique(acc, item): return acc if acc[-1][1] == item[1] else acc.append(item) or acc srt_enum = sorted(enumerate(lst), key=lambda (i, val): val) return [item[1] for item in sorted(reduce(append_unique, srt_enum, [srt_enum[0]]))] 

使用订购减lessvariables保留:

假设我们有一个列表:

 l = [5, 6, 6, 1, 1, 2, 2, 3, 4] 

减lessvariables(不足):

 >>> reduce(lambda r, v: v in r and r or r + [v], l, []) [5, 6, 1, 2, 3, 4] 

快5倍,但更复杂

 >>> reduce(lambda r, v: v in r[1] and r or (r[0].append(v) or r[1].add(v)) or r, l, ([], set()))[0] [5, 6, 1, 2, 3, 4] 

说明:

 default = (list(), set()) # user list to keep order # use set to make lookup faster def reducer(result, item): if item not in result[1]: result[0].append(item) result[1].add(item) return result reduce(reducer, l, default)[0] 

还有很多其他的答案build议不同的方式来做到这一点,但他们都是批量操作,其中一些扔掉原来的订单。 这可能是正确的,取决于你需要什么,但是如果你想按照每个值的第一个实例的顺序遍历值,并且你想立即删除重复对象,你可以使用这个发生器:

 def uniqify(iterable): seen = set() for item in iterable: if item not in seen: seen.add(item) yield item 

这将返回一个生成器/迭代器,所以您可以在任何可以使用迭代器的地方使用它。

 for unique_item in uniqify([1, 2, 3, 4, 3, 2, 4, 5, 6, 7, 6, 8, 8]): print(unique_item, end=' ') print() 

输出:

 1 2 3 4 5 6 7 8 

如果你想要一个list ,你可以这样做:

 unique_list = list(uniqify([1, 2, 3, 4, 3, 2, 4, 5, 6, 7, 6, 8, 8])) print(unique_list) 

输出:

 [1, 2, 3, 4, 5, 6, 7, 8] 

这是最快的pythonic解决schemecomaring其他人在答复中列出。

使用短路评估的实现细节允许使用列表理解,这足够快。 visited.add(item)总是返回None ,结果为False ,所以右边的or总是这样的expression式的结果。

时间自己

 def deduplicate(sequence): visited = set() adder = visited.add # get rid of qualification overhead out = [adder(item) or item for item in sequence if item not in visited] return out 

现在你可以使用Counter类:

 >>> import collections >>> c = collections.Counter([1, 2, 3, 4, 5, 6, 1, 1, 1, 1]) >>> c.keys() dict_keys([1, 2, 3, 4, 5, 6]) 

这里是一个例子,返回列表没有保留秩序的重复。 不需要任何外部input。

 def GetListWithoutRepetitions(loInput): # return list, consisting of elements of list/tuple loInput, without repetitions. # Example: GetListWithoutRepetitions([None,None,1,1,2,2,3,3,3]) # Returns: [None, 1, 2, 3] if loInput==[]: return [] loOutput = [] if loInput[0] is None: oGroupElement=1 else: # loInput[0]<>None oGroupElement=None for oElement in loInput: if oElement<>oGroupElement: loOutput.append(oElement) oGroupElement = oElement return loOutput 

如果你想删除重复(就地编辑,而不是返回新的列表),而不使用内置集,dict.keys,uniqify,counter

 >>> t = [1, 2, 3, 1, 2, 5, 6, 7, 8] >>> for i in t: ... if i in t[t.index(i)+1:]: ... t.remove(i) ... >>> t [3, 1, 2, 5, 6, 7, 8] 

使用集合

 a = [0,1,2,3,4,3,3,4] a = list(set(a)) print a 

使用独特的

 import numpy as np a = [0,1,2,3,4,3,3,4] a = np.unique(a).tolist() print a 

从列表中删除重复项的最佳方法是使用python中的set()函数,再次将其转换为列表

 In [2]: some_list = ['a','a','v','v','v','c','c','d'] In [3]: list(set(some_list)) Out[3]: ['a', 'c', 'd', 'v'] 

要删除重复项,请将其设置为SET,然后再将其设置为LIST并进行打印/使用。 一套保证有独特的元素。 例如 :

 a = [1,2,3,4,5,9,11,15] b = [4,5,6,7,8] c=a+b print c print list(set(c)) #one line for getting unique elements of c 

输出将如下(在Python 2.7中检查)

 [1, 2, 3, 4, 5, 9, 11, 15, 4, 5, 6, 7, 8] #simple list addition with duplicates [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 15] #duplicates removed!! 

我认为转换为设置是删除重复最简单的方法:

 list1 = [1,2,1] list1 = list(set(list1)) print list1 

你可以简单地使用集合来完成。

第一步:获取不同的列表元素
Step2获取列表的通用元素
第三步合并它们

 In [1]: a = ["apples", "bananas", "cucumbers"] In [2]: b = ["pears", "apples", "watermelons"] In [3]: set(a).symmetric_difference(b).union(set(a).intersection(b)) Out[3]: {'apples', 'bananas', 'cucumbers', 'pears', 'watermelons'} 
 def remove_duplicates(A): [A.pop(count) for count,elem in enumerate(A) if A.count(elem)!=1] return A 

清单复制删除重复

如果你不关心秩序,想要一些与上面提到的pythonic方法不同的东西(也就是说可以在面试中使用),那么:

 def remove_dup(arr): size = len(arr) j = 0 # To store index of next unique element for i in range(0, size-1): # If current element is not equal # to next element then store that # current element if(arr[i] != arr[i+1]): arr[j] = arr[i] j+=1 arr[j] = arr[size-1] # Store the last element as whether it is unique or repeated, it hasn't stored previously return arr[0:j+1] if __name__ == '__main__': arr = [10, 10, 1, 1, 1, 3, 3, 4, 5, 6, 7, 8, 8, 9] print(remove_dup(sorted(arr))) 

时间复杂度:O(n)

辅助空间:O(n)

参考: http : //www.geeksforgeeks.org/remove-duplicates-sorted-array/

没有使用设置

 data=[1, 2, 3, 1, 2, 5, 6, 7, 8] uni_data=[] for dat in data: if dat not in uni_data: uni_data.append(dat) print(uni_data)