Python 3 中的元素未从列表中删除

Element was not removed from list in Python 3

d = 3
cl = [1,3,4]

for i in cl:
    if i <= d:
        cl.remove(i)
print(cl)

输出 >> [3,4]

数字 3 不应该在列表中,因为它通过了 i <= d 条件,所以 cl.remove 应该被调用,但它在输出中。我在这里做错了什么?

发生这种情况是因为您在迭代列表时从列表中删除了元素。可以这样解决

[num for num in cl if num > d]

这个有效

d = 3
cl = [1, 3, 4]
for i in range(len(cl)):
    if cl[i-1] <= d:
        cl.remove(cl[i-1])
print(cl)

如果有效请采纳...

这是在迭代过程中改变数据结构的结果。 for 循环本质上是在您的列表上创建一个迭代器,每个项目都调用 next(iterator)。但是,弹出项目会改变迭代器正在查看的内容

a = [1, 2, 3, 4]

it = iter(a)

# First iteration
next(it)
1

# remove element
a.pop(0)
1

# we skipped 2!
next(it)
3

为什么?好吧,我们通过删除当前所在的元素有效地更改了迭代器指向的元素。我们正在查看序列中的第一个元素,但它已被删除,所以现在第二个元素是第一个元素。因此,对 next 的调用将指向以下元素。这最终看起来像是被跳过了,但实际上并没有,你只是无意中让元素向前移动了。

为避免这种情况,最好通过过滤创建一个新列表,正如@AlexanderLekontsev 在他的回答中所建议的那样。这避免了在迭代时发生变异。您可以使用带有附加功能的标准循环来执行此操作:

newlist = []

for num in cl:
    if num >= d:
        newlist.append(num)

本质上,因为您在迭代列表时从列表中删除元素,所以您跳过了值 3

在 for 循环的第一次迭代中,您删除了值 1。由于迭代在 Python 中的工作方式,在 for 循环的第二次迭代中,您正在寻找 next(next(cl))。但是,cl 已更新为 [3,4],因为您删除了 1。所以现在 next(next(cl)) = next(3) = 4 你已经跳过了 3.

您可以通过创建新列表并在进行时更新它来解决此问题。使用列表理解来做到这一点的简单方法就是 [num for num in cl if num > d].