我如何检查一个列表是否有任何重复,并返回一个没有重复的新列表?
当前回答
Test = [1,8,2,7,3,4,5,1,2,3,6]
Test.sort()
i=1
while i< len(Test):
if Test[i] == Test[i-1]:
Test.remove(Test[i])
i= i+1
print(Test)
其他回答
今天,一位同事将接受的答案作为他的代码的一部分发给了我进行代码审阅。 虽然我很欣赏这个问题答案的优雅,但我对他的表现并不满意。 我尝试过这个解决方案(我使用set来减少查找时间)
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
如果把set从解中移除会发生什么?
def ordered_set(inlist):
out_list = []
for val in inlist:
if not val in out_list:
out_list.append(val)
return out_list
结果并不像OrderedDict那样糟糕,但仍然是原始解决方案的3倍多
In [136]: %timeit ordered_set(x)
10000 loops, best of 3: 52.6 us per loop
减少变量与顺序保存:
假设我们有一个列表:
l = [5, 6, 6, 1, 1, 2, 2, 3, 4]
减少变体(无效):
>>> 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]
一个更好的方法是,
import pandas as pd
myList = [1, 2, 3, 1, 2, 5, 6, 7, 8]
cleanList = pd.Series(myList).drop_duplicates().tolist()
print(cleanList)
#> [1, 2, 3, 5, 6, 7, 8]
秩序得以维持。
另一种解决方案可能如下。以item为键,index为值,从列表中创建一个字典,然后打印字典键。
>>> 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]
为了完整起见,由于这是一个非常流行的问题,toolz库提供了一个独特的函数:
>>> tuple(unique((1, 2, 3)))
(1, 2, 3)
>>> tuple(unique((1, 2, 1, 3)))
(1, 2, 3)