首先免责声明:
我不想使用这样的代码,我知道这是一种不好的做法。同样,我对如何改进它,使它正确的技巧不感兴趣。我感兴趣的是一种理论。
这样的代码如何在python 3.6中工作:
ls = range(5)
for elem_a in ls:
ls = range(5, 10)
for elem_b in ls:
print(elem_a, elem_b)
我正在遍历ls时重新分配它的值。第一次执行ls
期间,第一次迭代中的for elem_a in ls
的值是否存储在内存中?
答案 0 :(得分:6)
重新分配要循环的变量无效,因为不会在每次迭代时都重新评估该变量。实际上,该循环在内部循环iterator,而不是在range
对象上。
基本上,如果您有这样的循环:
seq = range(5)
for elem in seq:
seq = something_else
Python将其重写为如下形式:
seq = range(5)
loop_iter = iter(seq) # obtain an iterator
while True:
try:
elem = next(loop_iter) # get the next element from the iterator
except StopIteration:
break # the iterator is exhausted, end the loop
# execute the loop body
seq = something_else
其中的关键方面是,循环对存储在iter(seq)
中的loop_iter
有自己的引用,因此自然地重新分配seq
对循环没有影响。
所有这些都在compound statement documentation中进行了解释:
for_stmt ::= "for" target_list "in" expression_list ":" suite ["else" ":" suite]
表达式列表只计算一次;它应该产生一个可迭代的 宾语。为
expression_list
的结果创建一个迭代器。 然后,套件将对由 迭代器,按迭代器返回的顺序。