[英]For-loop statement evaluation
已经同意for
循环中的可迭代项仅被评估一次。 因此, f called
的输出f called
被打印一次。
我正在努力弄清楚的是,为什么我没有得到一个out-of-bound error
? 由于在评估时,长度等于100
。
mylist = [x for x in range(100)]
def printmylist(thelist):
print("f called")
return thelist
for i, item in enumerate(printmylist(mylist)):
print(len(mylist))
del mylist[len(mylist) - i - 1]
f called 100 99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70 69 68 67 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51
在for
循环中,使用列表的当前长度来评估要删除的位置。 并且,您从列表的末尾删除。 所以你的循环只迭代50次。
如果更改print
语句以显示i
,您将发现它仅从0到49计数。
虽然print("f called")
只调用一次,但是在你的case中存储enumerate(printmylist(mylist))
的评估值的变量(称为iterable object
enumerate(printmylist(mylist))
不时地引用它的set
更改,因为你删除了枚举一个接一个。首先你有100个项目,但它逐个减少:
Note: len(mylist) - i - 1 = 99, delete index 99 -> 100 removed
1 2 3 ... 98 99 100 #len(mylist) = 100
^ <-- here is i = 0
Note: len(mylist) - i - 1 = 98, delete index 98 -> 99 removed
1 2 3 ... 98 99 #len(mylist) = 99
^ <-- here is i = 1
Note: len(mylist) - i - 1 = 97, delete index 97 -> 98 removed
1 2 3 ... 98 #len(mylist) = 98
^ <-- here is i = 2
... and so on
另外,因为i
将针对该变量( iterable object
检查循环的每一端,因此,您只打印100
项目中的50
100
项目。
从 Python for语句文档 :
表达式列表评估一次 ; 它应该产生一个可迭代的对象。 为
expression_list
的结果创建一个迭代器。 然后,对于迭代器提供的每个项,按升序索引的顺序执行一次该套件。 依次使用标准的分配规则将每个项目分配给目标列表 ,然后执行该套件。 当项目耗尽时 (当序列为空时立即),执行else
子句中的套件(如果存在),并且loop
终止 。
为了简化,想象一下
v = enumerate(printmylist(mylist)) #v is the iterable object
虽然它只被评估一次,但每次移除一个项目时,指向v
的set
都会发生变化,但i
会在v
迭代。 因此, i
将逐渐增加,直到最后i = 50
。
.
.
.
v = ... 50, i = 49
^ <-- here is i and is in v
v = ... 50 , i = 50 and is out from v
^ <-- no more item found
没有更多项目可以在边界之外进行评估。 这样你就得到了结果:
100 99 ... 51
并没有超出范围。
更多内容如何在内部工作 ,包括如何创建内部索引器并每次都根据终止值指向的值进行检查。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.