删除列表中的重复项
几乎我需要编写一个程序来检查一个列表是否有任何重复,如果它删除它们,并返回一个新的列表与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)