循环遍历列表的切片副本

Jos*_*hua 1 python

我试图理解循环列表循环列表的"切片"副本之间的区别.

因此,例如,在以下列表中,长度大于6的元素将附加到列表的开头:

words = ['cat', 'window', 'blahblah']

for word in words[:]:
    if len(word) > 6:
        words.insert(0, word)

print(words)

words = ['blahblah', 'cat', 'window', 'blahblah']
Run Code Online (Sandbox Code Playgroud)

然后,我运行以下内容,看看为什么它不是正确的方法,但我的翻译冻结了,我必须退出.为什么会这样?我只是在我的列表的开头添加一些内容,因为列表是可变的...

for word in words:
    if len(word) > 6:
        words.insert(0, word)
Run Code Online (Sandbox Code Playgroud)

有人可以帮我理解为什么这最后一点会阻止我的程序?

L3v*_*han 6

该清单words有三个要素.副本words也是.words如果当前元素超过6个字符,则迭代复制,插入内容,并完成.

现在让我们看看当你words直接迭代时会发生什么:

前两个迭代步骤很好,因为条件为False.但是,因为len('blahblah') > 6,您现在正在'blahblah'列表的开头插入.现在列表看起来像这样:

['blahblah', 'cat', 'window', 'blahblah']

你刚刚看到了第三个元素,所以现在循环继续并查看第四个元素,但是因为你在列表的开头插入了一些东西,所以列表的其余部分被移动了,而新的第四个元素又被移动'blahblah'了.blahblah仍然超过6个字符,您在开头再次插入它并陷入无限循环:

['cat', 'window', 'blahblah']
   ^
['cat', 'window', 'blahblah']
            ^
['cat', 'window', 'blahblah']
                       ^
['blahblah', 'cat', 'window', 'blahblah']
                                   ^
['blahblah', 'blahblah', 'cat', 'window', 'blahblah']
                                               ^
...
Run Code Online (Sandbox Code Playgroud)

  • 如果你在循环中编写`print words [:]`,它每次都会创建一个新副本,但是你迭代的副本不会改变.你可以通过在循环之前编写`copy = words [:]`,迭代`copy`并在循环中打印`copy`来看到它. (2认同)