Python – 迭代时如何从列表中删除项目?

我正在迭代Python中的元组列表,并且如果它们符合某些条件,我会尝试删除它们。

for tup in somelist:
    if determine(tup):
         code_to_remove_tup

我应该用什么代替code_to_remove_tup?我无法弄清楚如何以这种方式删除项目。


您可以使用列表推导来创建仅包含您不想删除的元素的新列表:

somelist = [x for x in somelist if not determine(x)]

或者,通过分配切片somelist[:],您可以改变现有列表以仅包含所需的项目:

somelist[:] = [x for x in somelist if not determine(x)]

如果有其他参考somelist需要反映更改,则此方法可能很有用。

你也可以使用而不是理解itertools。在Python 2中:

from itertools import ifilterfalse
somelist[:] = ifilterfalse(determine, somelist)

或者在Python 3中:

from itertools import filterfalse
somelist[:] = filterfalse(determine, somelist)

建议列表推导的答案几乎是正确的 – 除了它们构建一个全新的列表然后给它与旧列表相同的名称,它们不会修改旧的列表。这与你在选择性删除方面所做的不同,就像在@ Lennart的建议中一样 – 它更快,但是如果你的列表是通过多个引用访问的,那么你只是重新安装其中一个引用并且不改变列表对象本身可能导致微妙的,灾难性的错误。

幸运的是,获得列表推导的速度和就地更改所需的语义非常容易 – 只需代码:

somelist[:] = [tup for tup in somelist if determine(tup)]

注意与其他答案的细微差别:这个没有分配到一个名字 – 它分配给恰好是整个列表的列表切片,从而替换同一个Python列表对象中的列表内容 ,而不是仅仅重新设置一个引用(从之前的列表对象到新列表对象)就像其他答案一样。


您需要获取列表的副本并首先迭代它,否则迭代将失败,结果可能是意外结果。

例如(取决于列表的类型):

for tup in somelist[:]:
    etc....

一个例子:

>>> somelist = range(10)
>>> for x in somelist:
...     somelist.remove(x)
>>> somelist
[1, 3, 5, 7, 9]

>>> somelist = range(10)
>>> for x in somelist[:]:
...     somelist.remove(x)
>>> somelist
[]

for i in range(len(somelist) - 1, -1, -1):
    if some_condition(somelist, i):
        del somelist[i]

你需要倒退,否则就像锯掉你所坐的树枝一样:-)

Python的2个用户:更换range通过xrange避免产生硬编码列表

添加评论

友情链接:蝴蝶教程