如何使用列表推导从列表中删除重复项?

时间:2012-05-11 10:05:23

标签: python list-comprehension

如何使用列表推导从列表中删除重复项?我有以下代码:

a = [1, 2, 3, 3, 5, 9, 6, 2, 8, 5, 2, 3, 5, 7, 3, 5, 8]
b = []
b = [item for item in a if item not in b]

但它不起作用,只生成相同的列表。为什么它产生相同的清单?

8 个答案:

答案 0 :(得分:16)

它生成一个相同的列表,因为b在运行时不包含任何元素。 你想要的是什么:

>>> a = [1, 2, 3, 3, 5, 9, 6, 2, 8, 5, 2, 3, 5, 7, 3, 5, 8]
>>> b = []
>>> [b.append(item) for item in a if item not in b]
[None, None, None, None, None, None, None, None]
>>> b
[1, 2, 3, 5, 9, 6, 8, 7]

答案 1 :(得分:8)

如果你不介意使用与列表推导不同的技术,你可以使用一套:

>>> a = [1, 2, 3, 3, 5, 9, 6, 2, 8, 5, 2, 3, 5, 7, 3, 5, 8]
>>> b = list(set(a))
>>> print b
[1, 2, 3, 5, 6, 7, 8, 9]

答案 2 :(得分:4)

在使用keys中的值构建的dict上使用a作为其键。

b = dict([(i, 1) for i in a]).keys()

或使用一套:

b = [i for i in set(a)]

答案 3 :(得分:4)

列表未更改的原因是b开始为空。这意味着if item not in b始终为True。只有在生成列表后,才会将这个新的非空列表分配给变量b

答案 4 :(得分:3)

使用groupby

>>> from itertools import groupby
>>> a = [1, 2, 3, 3, 5, 9, 6, 2, 8, 5, 2, 3, 5, 7, 3, 5, 8]
>>> [k for k, _ in groupby(sorted(a, key=lambda x: a.index(x)))]
[1, 2, 3, 5, 9, 6, 8, 7]

如果您不关心值首先出现在原始列表中的顺序,请忽略关键参数,例如

>>> [k for k, _ in groupby(sorted(a))]
[1, 2, 3, 5, 6, 7, 8, 9]

您可以使用groupby做一些很酷的事情。识别多次出现的项目:

>>> [k for k, v in groupby(sorted(a)) if len(list(v)) > 1]
[2, 3, 5, 8]

或建立频率词典:

>>> {k: len(list(v)) for k, v in groupby(sorted(a))}
{1: 1, 2: 3, 3: 4, 5: 4, 6: 1, 7: 1, 8: 2, 9: 1}

itertools模块中有一些非常有用的功能:chainteeproduct等等!

答案 5 :(得分:1)

>>> a = [10,20,30,20,10,50,60,40,80,50,40,0,100,30,60]
>>> [a.pop(a.index(i, a.index(i)+1)) for i in a if a.count(i) > 1]
>>> print(a)

答案 6 :(得分:0)

>>> from itertools import groupby
>>> repeated_items = [2,2,2,2,3,3,3,3,4,5,1,1,1]
>>> [
...     next(group)
...     for _, group in groupby(
...         repeated_items,
...         key=lambda x: repeated_items.index(x)
...     )
... ]
[2, 3, 4, 5, 1]

答案 7 :(得分:0)

对于Python 3.6+,与Niek de Klein's mostly excellent solution相比有一个改进(它的主要缺陷是它失去了输入顺序)。由于dict现在已按插入顺序排序,因此您可以执行以下操作:

b = list(dict.fromkeys(a))

在早期的Python上,您可以这样做:

from collections import OrderedDict

b = list(OrderedDict.fromkeys(a))

虽然并没有那么快(即使将OrderedDict移到C层,它也保留了很多开销来支持不支持它们的dict避免重新排序操作)