我试图了解循环列表与循环遍历"切片"之间的区别列表副本。
因此,例如,在以下列表中,长度大于6的元素将附加到列表的开头:
words = ['cat', 'window', 'blahblah']
for word in words[:]:
if len(word) > 6:
words.insert(0, word)
print(words)
words = ['blahblah', 'cat', 'window', 'blahblah']
然后,我运行以下内容,看看为什么它不是正确的方法,但我的翻译冻结了,我必须退出。为什么会这样?我只是在我的列表的开头添加一些内容,因为列表是可变的...
for word in words:
if len(word) > 6:
words.insert(0, word)
有人可以帮我理解为什么这最后一点会阻止我的程序吗?
答案 0 :(得分:6)
列表words
有三个要素。 words
的副本也可以。如果当前元素超过6个字符,则迭代副本,在words
中插入内容,并完成。
现在让我们看看当你直接迭代words
时会发生什么:
前两个迭代步骤很好,因为条件为False。但是从len('blahblah') > 6
开始,您现在在列表的开头插入'blahblah'
。现在列表如下:
['blahblah', 'cat', 'window', 'blahblah']
你刚刚看到了第三个元素,所以现在循环继续并查看第四个元素,但是因为你在列表的开头插入了一些内容,所以列表的其余部分移位了,新的第四个元素是{{1再次。 'blahblah'
仍然超过6个字符,您在开头再次插入它并陷入无限循环:
blahblah
答案 1 :(得分:2)
在第一种方法中,您正在执行列表words
的浅表副本,对其进行迭代并将长单词附加到列表words
。所以你迭代一个固定的列表,并扩展一个不同的列表。
使用您的上一个方法,列表words
随着每次迭代而增长,因此当您循环遍历它并且它不断增长时,您处于无限循环中。
答案 2 :(得分:2)
当您执行words[:]
时,您正在迭代列表副本,而使用words
,您正在迭代列表的原始副本。
在II
的情况下,您的解释器处于冻结状态,因为当您处于最后一个索引时,条件已满足并且您将该项插入列表的开头。现在,还有一个索引需要循环迭代。同样,条件满足并且它继续这样,导致无限循环。
words[:]
的情况并非如此,因为您要追加的列表与您正在迭代的列表不同。
答案 3 :(得分:2)
以下循环
for word in words:
// do something
大致相当于下一个(当words
是列表而不是另一种iterable
时):
i = 0
while i != len(words):
word = words[i]
// do something (assuming no 'continue' here)
i += 1
因此,在循环时,在当前位置之前将某些内容插入到列表中,然后在下一次迭代中,您最终会处理与上一次迭代相同的元素。在您的情况下,这会导致无限循环。
答案 4 :(得分:1)
words[:]
表示words
的新副本,长度已修复。所以你正在迭代一个固定的列表。
但是在第二种情况下,迭代并扩展使其无限的相同列表。
words = ['cat', 'window', 'blahblah']
new_words = [_ for _ in words if len(_) > 6]
print(new_words)
答案 5 :(得分:-1)
如果您想了解在插入列表(单词)与切片副本(单词[:])的背景下到底发生了什么,可以更改/制表以查看无限循环,就像无限循环一样在脚本的原始位置看不到:
for w in words:
if len(w) > 6:
words.insert(0, w)
print(words) #prints after each insert, let you see the infinite loop