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

这个python列表删除循环有什么问题?,python,list,loops,Python,List,Loops,今晚我在一个很长的节目上工作了很长时间。但我遇到了一个简单的障碍。有人能告诉我为什么这个代码是这样工作的吗 我有两张单子。我希望列表2只包含不在列表1中的数字。 从逻辑上看,这似乎应该奏效。但它确实起了作用。为什么? 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) retu

今晚我在一个很长的节目上工作了很长时间。但我遇到了一个简单的障碍。有人能告诉我为什么这个代码是这样工作的吗

我有两张单子。我希望列表2只包含不在列表1中的数字。 从逻辑上看,这似乎应该奏效。但它确实起了作用。为什么?

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]

为什么?


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

当你修改你正在迭代的序列时,它会产生意想不到的结果。我会这样做,它利用了快速
set
操作

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

这比使用列表理解更快还是更慢取决于
list1
list2
的大小,以及您是否可以将一个列表作为初始化的一部分而不是在循环中多次修改成一个

您想要的可以通过列表理解直接表达:

list2 = [ch for ch in list2 if ch not in list1]
它更具可读性,与集合解决方案不同,它不会从列表2中删除重复项或更改项目顺序

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

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

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

在python中,当您对in列表使用
时,python会按顺序查看列表中的元素1、元素2等。所以它首先查看12并删除它。然后看元素2,除了15是元素1,16是元素2。它删除了16个。因此,15从未被选中,并留在列表中。然后它同样跳过7并删除34


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

这是一个很好的观点。虽然您可能希望将
list1
转换为
set
。这也是我的想法,但代码不应该删除
12
,因为它不在
list1