我今晚在长期计划上工作太久了。但我遇到了一个简单的障碍。任何人都可以告诉我为什么这段代码按照它的方式工作?
我有两个清单。我希望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]
为什么?
我怎样才能完成我的需要?
答案 0 :(得分:8)
修改正在迭代的序列时,会产生意外结果。我这样做,利用快速set
操作。
list2 = list(set(list2) - set(list1))
这是否比使用列表推导更快或更慢取决于list1
和list2
的大小,以及是否可以在初始化时将其作为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 ......
避免这种情况的方法当然不是在要删除元素的同一列表上进行迭代。您可以复制第二个列表。检查此副本中的成员是否在第一个列表中。如果不是,请将其从第二个列表中删除。我相信已发布的一些建议对您有用。这是解释。