循环/迭代列表时删除项目

时间:2017-03-30 16:24:05

标签: python for-loop

我看到一些关于如何处理循环列表时删除项目的任务的讨论,例如this post

this link中的答案说:

  

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

我似乎可以毫无问题地做到这一点:

words = ['DROP', 'TABLE', 'table_name']

for ii, word in enumerate(words):

    print(ii)
    print(word)

    if words[ii] == 'DROP' and words[ii + 1] == 'TABLE':    
        words[ii] = 'DROP TABLE'
        del words[ii + 1]

print(words)

的产率:

0
DROP
1
table_name
['DROP TABLE', 'table_name']

python是否更改了限制,我们现在可以在循环时删除项目? 我使用的是python 3.7。

3 个答案:

答案 0 :(得分:3)

根据您提供的答案评论:

  

"You are not permitted" - sure you are. Python doesn't complain at you, it just gives a slightly (read: completely) different result to what people might expect. – lvc May 19 '12 at 14:00

您总是可以从for循环中删除项目,但在循环时它会跳过迭代。以这个例子来看看会发生什么(通过Python 2.7和Python 3.5运行得到相同的结果,当然Python 2有print i):

i=[1,2,3,4,5,6]

for x in i:
    i.remove(x)

print(i) #[2, 4, 6] 

注意它如何跳过索引2,4,6?这是因为当您在value 1中删除index 0时,value 2成为新index 0,而for循环将value 3作为下一个索引。

没有什么新鲜事。通常,直接删除项目是个坏主意  从列表中迭代它。

您的代码看起来很好的原因是您故意删除了索引1,这正是您所希望的。

答案 1 :(得分:1)

该陈述在技术上是错误的,但对于大多数用例来说是合理的。您肯定可以在枚举时从列表中删除项目,但请注意,如果您这样做,最终将跳过元素。您希望在您的情况下发生这种情况 - 枚举通过对尚未枚举的列表(words[ii + 1] == 'TABLE')进行预测并修剪来跳过“TABLE”条目。但这是一个不常见的用例。

答案 2 :(得分:1)

有(也是)绝对没有什么能阻止你修改你正在迭代的列表(虽然字典不能在python3中修改 - 导致错误),但结果可能......令人惊讶。即使你的问题也是基于这样令人惊讶的结果 - 你没有错误,因为你展望未来并将两个结果合并为一个。如果你只删除每个DROP,你最终会遗漏一些条目:

words = ['DROP', 'one_drop_will_be_missed', 'DROP', 'DROP' ]

for ii, word in enumerate(words):
    print(ii)
    print(word)
    if words[ii] == 'DROP':
        del words[ii]

print(words)

结果:

0
DROP
1
DROP
['one_drop_will_be_missed', 'DROP']

如果以某种方式DROP成为列表中的最后一个字,会发生什么?