猿问

关于从列表中删除项目-在迭代过程中-这个成语有什么问题?

从列表中删除项目-在迭代过程中-这个成语有什么问题?

作为一个实验,我做了这个:

letters=['a','b','c','d','e','f','g','h','i','j','k','l']for i in letters:
    letters.remove(i)print letters

最后的打印显示不是所有的项目都被删除了?(每个人都是)。

IDLE 2.6.2      >>> ================================ RESTART ================================>>> ['b', 'd', 'f', 'h', 'j', 'l']>>>

对此有什么解释?它怎么能被重写以删除每一项?



白衣染霜花
浏览 376回答 3
3回答

倚天杖

有些答案解释了为什么会发生这种情况,有些则解释了你应该做什么。我会无耻地把这些碎片拼凑在一起。原因是什么?因为Python语言旨在以不同的方式处理这个用例。文件明确指出:在循环中修改正在迭代的序列是不安全的(这只能发生在可变序列类型(例如列表)上)。如果您需要修改正在迭代的列表(例如,要复制选定的项),则必须对副本进行迭代。.强调我的。有关更多信息,请参见链接页面-文档是有版权的,所有的权利都是保留的。你可以很容易地理解为什么你得到了你所拥有的,但它基本上是未定义行为这可以很容易地改变,没有警告从构建到构建。别这么做。就像不知道为什么i += i++ + ++i不管是什么,行在你的体系结构上,在你为你的语言的编译器的特定构建上所做的事情。-包括但不限于砸你的电脑和让恶魔从你的鼻子里飞出来 :)它怎么能被重写以删除每一项?del letters[:](如果需要更改对此对象的所有引用)letters[:] = [](如果需要更改对此对象的所有引用)letters = [](如果您只想使用新对象)也许你只是想根据某种条件删除一些物品?在这种情况下,您应该迭代列表的副本。创建副本的最简单方法是制作一个包含整个列表的切片,其中包含[:]语法,如下所示:#remove unsafe commandscommands = ["ls", "cd", "rm -rf /"]for cmd in commands[:]:   if "rm " in cmd:     commands.remove(cmd)如果您的检查并不特别复杂,您可以(而且可能应该)筛选:commands = [cmd for cmd in commands if not is_malicious(cmd)]

精慕HU

不能同时迭代列表并对其进行变异,而只能迭代一个片段:letters=['a','b','c','d','e','f','g','h','i','j','k','l']for i in letters[:]: # note the [:] creates a slice      letters.remove(i)print letters尽管如此,对于这样的简单操作,您应该简单地使用:letters = []
随时随地看视频慕课网APP
我要回答