如何在 Python 中删除 for 循环中的列表元素?

我有个名单

a = ["a", "b", "c", "d", "e"]

我想在 for 循环中移除这个列表中的元素,如下所示:

for item in a:
print(item)
a.remove(item)

但是没用,我能做什么?

259198 次浏览

使用 for循环在列表上迭代时,不允许从列表中删除元素。

重写代码的最佳方法取决于您想要做什么。

例如,您的代码相当于:

for item in a:
print(item)
a[:] = []

或者,您可以使用 while循环:

while a:
print(a.pop())

I'm trying to remove items if they match a condition. Then I go to next item.

您可以将 没有匹配条件的每个元素复制到第二个列表中:

result = []
for item in a:
if condition is False:
result.append(item)
a = result

或者,你可以使用 filter或列表内涵,把结果分配回 a:

a = filter(lambda item:... , a)

或者

a = [item for item in a if ...]

其中 ...代表需要检查的条件。

如何创建一个新的列表和添加元素,您想要的新列表。在迭代列表时不能移除元素

重复执行列表的副本:

>>> a = ["a", "b", "c", "d", "e"]
>>> for item in a[:]:
print(item)
if item == "b":
a.remove(item)


a
b
c
d
e
>>> print(a)
['a', 'c', 'd', 'e']

正如其他答案所说,做到这一点的最佳方法是创建一个新的列表——要么在一个副本上迭代,要么构建一个只包含所需元素的列表,然后将其分配回同一个变量。这些变量之间的区别取决于您的用例,因为它们对原始列表的其他变量的影响是不同的(或者,更确切地说,第一个变量影响它们,第二个变量不影响它们)。

如果出于某种原因,副本不是一个选项,那么还有另外一个选项,它依赖于理解为什么要修改迭代中断的列表。列表迭代的工作方式是跟踪索引,在循环中每次递增索引,直到索引从列表末尾消失。因此,如果在当前索引处(或之前)移除,则从该点到结束的所有内容都向左移动一个点。但是迭代器不知道这一点,因为它现在位于 目前索引而不是下一个元素,所以它有效地跳过了下一个元素。但是,删除当前索引中的 之后内容并不会影响这些内容。

这意味着如果你从前向后迭代这个列表,如果你移除了当前索引中的一个元素,那么它右边的所有元素都会向左移动——但这并不重要,因为你已经处理了当前位置右边的所有元素,而且你正在向左移动——向左移动的下一个元素不会受到变化的影响,所以迭代器会给出你所期望的元素。

译者:

>>> a = list(range(5))
>>> for b in reversed(a):
if b == 3:
a.remove(b)
>>> a
[0, 1, 2, 4]

然而,制作一个副本通常是更好的方式,使您的代码容易阅读。我只是为了完整起见才提到这种可能性。

import copy


a = ["a", "b", "c", "d", "e"]


b = copy.copy(a)


for item in a:
print(item)
b.remove(item)
a = copy.copy(b)

工作原理: 为了避免更改正在迭代的列表,需要复制一个 a,对其进行迭代,并从 b中删除项目。然后将 b(修改后的副本)复制回 a

也许现在回答这个问题有点晚了,但是我刚刚发现了这个线程,并且我以前为它创建了自己的代码..。

    list = [1,2,3,4,5]
deleteList = []
processNo = 0
for item in list:
if condition:
print(item)
deleteList.insert(0, processNo)
processNo += 1


if len(deleteList) > 0:
for item in deleteList:
del list[item]

这可能是一个漫长的道路做到这一点,但似乎工作得很好。我创建了第二个列表,它只保存与要删除的列表项相关的数字。请注意,“插入”在位置0插入列表项目编号,并推动其余项目,以便在删除项目时,列表从最高的数字删除回到最低的数字,以便列表保持顺序。