【问题标题】:Removing items from a list in a loop [duplicate]从循环中的列表中删除项目[重复]
【发布时间】:2011-11-05 19:41:33
【问题描述】:

很长一段时间以来,我一直在尝试找出一种方法来遍历列表并删除我所在的当前项目。我似乎无法让这个工作如我所愿。它只循环 1 次,但我希望它循环 2 次。当我移除移除线时 - 它会循环 2 次。

a = [0, 1]
for i in a:
    z = a
    print z.remove(i)

输出:

[1]

我期待的输出:

[1] 
[0]

【问题讨论】:

  • 我不知道为什么你会得到任何输出。我以为z.remove(i) 会返回None

标签: python list


【解决方案1】:

您在迭代列表时正在更改列表 -- z = a 不会复制,它只是将 z 指向同一位置 a 点。

试试

for i in a[:]:          # slicing a list makes a copy
    print i             # remove doesn't return the item so print it here
    a.remove(i)         # remove the item from the original list

while a:                # while the list is not empty
    print a.pop(0)      # remove the first item from the list

如果您不需要显式循环,则可以删除与列表解析条件匹配的项目:

a = [i for i in a if i] # remove all items that evaluate to false
a = [i for i in a if condition(i)] # remove items where the condition is False

【讨论】:

  • 现在的输出是“None None”
  • remove 不返回任何内容,因此它打印 None。如果您想在删除之前打印该项目,只需执行print i 然后a.remove(i)pop 版本实际上返回给定索引处的项目,因此它将print 项目。编辑了我的答案以反映这一点。
【解决方案2】:

在循环遍历列表时修改列表是一种不好的做法。创建列表的副本:

oldlist = ['a', 'b', 'spam', 'c']
newlist = [x for x in oldlist if x != 'spam']

要修改原始列表,请使用切片分配将副本原地写回:

oldlist[:] = [x for x in oldlist if x != 'spam']

† 关于为什么这可能是不好的做法的要点,请考虑当序列在迭代期间发生变化时,iterator 在序列上的实现细节。如果您删除了当前项,迭代器应该指向原始列表中的下一项还是修改后的列表中的下一项?如果您的决策程序改为将上一个(或下一个)项删除到当前项呢?

【讨论】:

    【解决方案3】:

    问题是您正在用remove 修改a,因此循环退出,因为索引现在超出了它的末尾。

    【讨论】:

    • 那么他应该怎么做呢?
    • 我不是 python 人,所以我必须查找语法,但我假设您可以使用 while removewhile pop
    • 我知道,我只是说你没有真正回答这里的问题,因为你没有告诉他该怎么做。
    【解决方案4】:

    在循环列表时不要尝试删除列表的多个项目。我认为这是一个一般规则,你不仅应该在 python 中遵循,而且在其他编程语言中也应该遵循。

    您可以将要删除的项目添加到单独的列表中。然后从原始列表中删除该新列表中的所有对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-06
      • 1970-01-01
      • 2021-11-28
      • 2019-03-14
      • 1970-01-01
      • 2012-01-08
      • 2014-06-12
      相关资源
      最近更新 更多