如何检查列表是否有任何重复项,并返回一个没有重复项的新列表?
下面的代码是用于在列表中去除重复项的简单方法
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]
list(set(..))
(超过100万次)将比此解决方案快约10秒钟 - 而此方法需要大约12秒钟,list(set(..))
仅需要约2秒钟! - dylnmcdef 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
def remove_duplicates(A):
[A.pop(idx) for idx,elem in enumerate(A) if A.count(elem)!=1]
return A
如果您想删除重复项(原地编辑而不返回新列表),而不使用内置的set、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]
enumerate()
函数可以更快地获取索引:for i, value in enumerate(t): if value in t[i + 1:]: t.remove(value)
- Martijn Pieters这里有一个例子,返回不重复的列表并保留顺序。不需要任何外部导入。
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
我认为将其转换为集合是去除重复项的最简单方法:
list1 = [1,2,1]
list1 = list(set(list1))
print list1
我没有看到关于不可哈希值的答案,这里是一个一行代码、n log n时间复杂度、仅使用标准库的答案:
list(map(operator.itemgetter(0), itertools.groupby(sorted(items))))
或者作为生成器函数:
def unique(items: Iterable[T]) -> Iterable[T]:
"""For unhashable items (can't use set to unique) with a partial order"""
yield from map(operator.itemgetter(0), itertools.groupby(sorted(items)))
set(..)
(如果元素是可哈希的,则速度较快),或者列表(缺点是它会导致 O(n2) 算法)。set(..)
,对于不可哈希的物品使用 list(..)
。此外,它被实现为一个生成器,因此我们可以限制项目数量,或进行其他过滤。key
参数来指定元素应该以何种方式唯一。例如,如果我们想要过滤字符串列表,使得输出中的每个字符串长度都不同,就可以使用它。def uniq(iterable, key=lambda x: x):
seens = set()
seenl = []
for item in iterable:
k = key(item)
try:
seen = k in seens
except TypeError:
seen = k in seenl
if not seen:
yield item
try:
seens.add(k)
except TypeError:
seenl.append(k)
我们现在比如可以这样使用它:
>>> list(uniq(["apple", "pear", "banana", "lemon"], len))
['apple', 'pear', 'banana']
>>> list(uniq(["apple", "pear", "lemon", "banana"], len))
['apple', 'pear', 'banana']
>>> list(uniq(["apple", "pear", {}, "lemon", [], "banana"], len))
['apple', 'pear', {}, 'banana']
>>> list(uniq(["apple", "pear", {}, "lemon", [], "banana"]))
['apple', 'pear', {}, 'lemon', [], 'banana']
>>> list(uniq(["apple", "pear", {}, "lemon", {}, "banana"]))
['apple', 'pear', {}, 'lemon', 'banana']
frozenset
是可哈希的,而set
则不是,如果它们具有相同的值,则它们是相等的,但在此代码中,您将把它们视为不相等。 - ShadowRangerset(..)
,这根本不起作用,而通过使用list
,这将导致线性查找时间。因此,它被认为是一个“更好”的集合,但也有一些缺陷。 - Willem Van Onsemset(..)
在极少数情况下还会返回不相等的对象。例如 math.nan
不等于 math.nan
,但由于字典首先检查引用相等性,因此字典将返回它。 - Willem Van Onsemkey=lambda x: x
,你可以使用 key=None
并且输入 k = key(item) if key else item
。这样会稍微快一点,并且得到相同的结果。 - Timothy C. Quinn>>> lst = [1, 3, 4, 2, 1, 21, 1, 32, 21, 1, 6, 5, 7, 8, 2]
>>>
>>> dict_enum = {item:index for index, item in enumerate(lst)}
>>> print dict_enum.keys()
[32, 1, 2, 3, 4, 5, 6, 7, 8, 21]
list(set(lst))
可以实现相同的逻辑结果。 - ShadowRangerlist(dict.fromkeys(lst))
。 - BrayoniIn [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'}
[1, 2, 3, 4, 5, 2, 4]
->[1, 3, 5]
,因为2和4是重复的。 - 9769953[1,2,3,1]→[1,2,3]
)是否有意义? 接受的答案暗示了可能实现第二个子问题的方法(即[1,2,3,1]→[2,3]
)。 目前,问题和最佳答案在某种程度上不完全同步。 - Mateen Ulhaq