循环遍历列表的切片副本

时间:2016-09-29 10:11:30

标签: 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']

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

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

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

6 个答案:

答案 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