这个python列表删除循环有什么问题?

时间:2011-11-29 06:07:42

标签: python list loops

我今晚在长期计划上工作太久了。但我遇到了一个简单的障碍。任何人都可以告诉我为什么这段代码按照它的方式工作?

我有两个清单。我希望list2只包含不在list1中的数字。 从逻辑上讲,这似乎应该有效。但它完全没有。为什么?

list1 = [1,2,3,4,5,6,7,8]
list2 = [12,15,16,7,34,23,5,23,76,89,9,45,4]


for ch in list2:
    if ch in list1:
         list2.remove(ch)

return list2

不知何故,这会返回:     [15,7,5,23,76,9,4]

为什么?

我怎样才能完成我的需要?

3 个答案:

答案 0 :(得分:8)

修改正在迭代的序列时,会产生意外结果。我这样做,利用快速set操作。

list2 = list(set(list2) - set(list1))

这是否比使用列表推导更快或更慢取决于list1list2的大小,以及是否可以在初始化时将其作为set而不是循环多次。

答案 1 :(得分:5)

迭代时不要修改列表。

你想要什么可以用列表理解直接表达:

list2 = [ch for ch in list2 if ch not in list1]

它更具可读性,与具有集合的解决方案不同,它不会从list2中删除重复项或更改项目顺序。

更新:当list1很大时,从中创建一个集合实际上会加快速度:

list2 = [ch for ch in list2 if ch not in set(list1)]

答案 2 :(得分:1)

这是一个有趣的观点。让我解释为什么会发生这种情况。

在python中使用for a in list时,python会依次查看列表的元素1,元素2等。所以它首先看12并删除它。然后它查看元素2,除了现在15是元素1而16是元素2.它删除16.所以15从未被检查过并留在列表中。然后它同样跳过7并删除34 ......

避免这种情况的方法当然不是在要删除元素的同一列表上进行迭代。您可以复制第二个列表。检查此副本中的成员是否在第一个列表中。如果不是,请将其从第二个列表中删除。我相信已发布的一些建议对您有用。这是解释。