在列表中查找唯一项,并使用列表推导将它们添加到新列表中

时间:2014-01-15 00:13:09

标签: python list list-comprehension

给定myList1

myList1 = [5,3,7,2,88,42,2,4,3,7,2]

我想将myList1的所有项目添加到myList2,但每个唯一项目只需添加一次。 所以我期待这样的列表:

[5, 3, 7, 2, 88, 42, 4]

我想用列表理解来做这件事。我试过这个,但它再次给了我与myList1

相同的项目
myList2 = []
myList2 = [item for item in myList1 if item not in myList2]

我做错了什么?

4 个答案:

答案 0 :(得分:5)

首先假设您关心维护订单:如果我使用list-comp,我倾向于这样做:

seen = set()
myList2 = [x for x in myList1 if x not in seen and not seen.add(x)]

或者替代

from collections import OrderedDict
myList2 = list(OrderedDict.fromkeys(myList1))

这两种方法都是O(n)。执行此操作时必须小心,不要通过对index进行重复的成员资格测试(或list搜索)来使算法为O(n ** 2)。

如果你关心订单,你真的只想做:

mySet = set(myList1)

答案 1 :(得分:2)

您看到列表中所有元素的原因是因为myList2仅在理解完成后被设置为新列表(由理解创建)。这意味着在列表理解中它始终将myList2视为空列表,因此每个项目都不在列表中,因此它将其放入新列表中。

如果您使用set,则可以轻松完成此任务。

myList1 = [5,3,7,2,88,42,2,4,3,7,2]


s = list(set(myList1))

print s

答案 2 :(得分:2)

如果你真的想要使用列表理解,并且你不想按照建议使用set

[myList1[i] for i in range(len(myList1)) if not myList1[i] in myList1[:i]]

答案 3 :(得分:1)

关于如何正确行事的许多好建议。 为什么您的代码不起作用的简要说明在这里可能会有所帮助。在myList2 = [item for item in myList1 if item not in myList2]中,if item not in myList2myList2为空时,在循环开始时对其进行一次评估。在以下示例中,if item not in myList2将位于每个循环中,在此期间新值也会附加到myList2

>>> myList1 = [5,3,7,2,88,42,2,4,3,7,2]
>>> myList2 = []
>>> for item in myList1:
    if item not in myList2:
        myList2.append(item)        
>>> myList2
[5, 3, 7, 2, 88, 42, 4]

我们得到了预期的结果。