简体   繁体   English

迭代列表Python

[英]Iterating over list Python

Can somebody tell me what's the difference between this code: 有人能告诉我这段代码有什么区别:

x = [1, 2, 3, 4, 5, 6, 7]
for i in x[:]:
    if i == 5:
        x.insert(0, i)

And this code: 这段代码:

x = [1, 2, 3, 4, 5, 6, 7]
for i in x:
    if i == 5:
        x.insert(0, i)

Why the second one won't work? 为什么第二个不起作用? I know it is mentioned in the Python tutorial, but I can't quite understand it. 我知道它在Python教程中提到过,但我不太明白。

In the first version, you create a copy (by slicing the list from the beginning to the end), in the second one you're iterating over the original list. 在第一个版本中,您创建一个副本(通过从开头到结尾切片列表),在第二个版本中,您将迭代原始列表。

If you iterate over a container, its size can't change during iteration, for good reasons (see below). 如果迭代容器,其大小在迭代期间不会改变,原因很充分(见下文)。 But since you call x.insert , the size of your list changes. 但是,因为您调用x.insert ,列表的大小会发生变化。


If you execute the second version, it actually doesn't throw an error immediately, but continues indefinitely, filling the list up with more and more 5s: 如果你执行第二个版本,它实际上不会立即抛出错误,而是无限期地继续,使用越来越多的5s填充列表:

Once you're at the list index 4 (and i is therefore 5), you're inserting a 5 at the beginning of the list: 一旦你在列表索引4(因此i是5),你在列表的开头插入一个5:

[5, 1, 2, 3, 4, 5, 6, 7]

You then continue in the loop, implicitly increasing your index to 5, which is now again 5, because the whole list got shifted one to the right, due to your insertion, so 5 will be inserted again: 然后你继续循环,隐式地将你的索引增加到5,现在又是5,因为你的插入导致整个列表向右移动了一次,所以将再次插入5:

[5, 5, 1, 2, 3, 4, 5, 6, 7]

This goes on "forever" (until there's a MemoryError ). 这将继续“永远”(直到有一个MemoryError )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM