我如何检查一个列表是否有任何重复,并返回一个没有重复的新列表?


当前回答

今天,一位同事将接受的答案作为他的代码的一部分发给了我进行代码审阅。 虽然我很欣赏这个问题答案的优雅,但我对他的表现并不满意。 我尝试过这个解决方案(我使用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

其他回答

简单易行:

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]

您可以通过使用集合简单地做到这一点。

步骤1:获取列表的不同元素 Step2获取列表的公共元素 3 .结合

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'}

尝试使用集合:

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

print t | t1
print t - t1

有许多其他的答案提出了不同的方法,但它们都是批处理操作,其中一些会抛弃原始的顺序。这可能是可以的,这取决于你需要什么,但如果你想在每个值的第一个实例的顺序上迭代值,并且你想要立即删除重复的值而不是一次性删除,你可以使用这个生成器:

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

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

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]

不幸的是。这里的大多数答案要么不保持顺序,要么太长。这里有一个简单的、有序的答案。

s = [1,2,3,4,5,2,5,6,7,1,3,9,3,5]
x=[]

[x.append(i) for i in s if i not in x]
print(x)

这将得到x,删除重复项,但保留顺序。