for循环中python变量的范围
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15363138/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Scope of python variable in for loop
提问by firecast
Heres the python code im having problems with:
这是我遇到问题的python代码:
for i in range (0,10):
if i==5:
i+=3
print i
I expected the output to be:
我预计输出是:
0
1
2
3
4
8
9
however the interpreter spits out:
然而口译员吐出:
0
1
2
3
4
8
6
7
8
9
I know that a forloop creates a new scope for a variable in C, but have no idea about python. Can anyone explain why the value of idoesnt change in the forloop in python and whats the remedy to it to get the expected output.
我知道for循环为 C 中的变量创建了一个新的作用域,但不知道 python。任何人都可以解释为什么pythoni中的for循环中的值没有改变,以及获得预期输出的补救措施是什么。
采纳答案by Junuxx
The for loop iterates over all the numbers in range(10), that is, [0,1,2,3,4,5,6,7,8,9].
That you change the currentvalue of ihas no effect on the next value in the range.
for 循环遍历 中的所有数字range(10),即[0,1,2,3,4,5,6,7,8,9]。
您更改 的当前值i不会影响范围中的下一个值。
You can get the desired behavior with a while loop.
您可以通过 while 循环获得所需的行为。
i = 0
while i < 10:
# do stuff and manipulate `i` as much as you like
if i==5:
i+=3
print i
# don't forget to increment `i` manually
i += 1
回答by Hoopdady
I gets reset every iteration, so it doesn't really matter what you do to it inside the loop. The only time it does anything is when i is 5, and it then adds 3 to it. Once it loops back it then sets i back to the next number in the list. You probably want to use a whilehere.
我每次迭代都会被重置,所以你在循环中对它做什么并不重要。它做任何事情的唯一时间是当 i 为 5 时,然后将其加 3。一旦它循环回来,它就会将 i 设置回列表中的下一个数字。您可能想在while此处使用 a 。
回答by user4815162342
Python's forloop simply loops over the provided sequence of values — think of it as "foreach". For this reason, modifying the variable has no effect on loop execution.
Python 的for循环只是在提供的值序列上循环——将其视为“foreach”。因此,修改变量对循环执行没有影响。
This is well described in the tutorial.
这在教程中有很好的描述。
回答by Claudiu
A for loop in Python is actually a for-each loop. At the start of each loop, iis set to the next element in the iterator (range(0, 10)in your case). The value of igets re-set at the beginning of each loop, so changing it in the loop body does not change its value for the next iteration.
Python 中的 for 循环实际上是一个 for-each 循环。在每个循环开始时,i设置为迭代器range(0, 10)中的下一个元素(在您的情况下)。的值i在每个循环开始时重新设置,因此在循环体中更改它不会更改下一次迭代的值。
That is, the forloop you wrote is equivalent to the following while loop:
也就是说,for你写的循环相当于下面的while循环:
_numbers = range(0, 10) #the list [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
_iter = iter(_numbers)
while True:
try:
i = _iter.next()
except StopIteration:
break
#--YOUR CODE HERE:--
if i==5:
i+=3
print i
回答by Jon Clements
If for some reason you did really want to change add 3 to iwhen it's equal to 5, and skip the next elements (this is kind of advancing the pointer in C 3 elements), then you can use an iterator and consume a few bits from that:
如果出于某种原因,您确实想将 add 3 更改为i等于5,并跳过下一个元素(这是在 C 3 元素中推进指针的一种),那么您可以使用迭代器并从中消耗一些位:
from collections import deque
from itertools import islice
x = iter(range(10)) # create iterator over list, so we can skip unnecessary bits
for i in x:
if i == 5:
deque(islice(x, 3), 0) # "swallow up" next 3 items
i += 3 # modify current i to be 8
print i
0
1
2
3
4
8
9
回答by hughdbrown
Analogy with C code
与 C 代码的类比
You are imagining that your for-loopin python is like this C code:
你想象你for-loop在 python 中是这样的 C 代码:
for (int i = 0; i < 10; i++)
if (i == 5)
i += 3;
It's more like this C code:
它更像是这个 C 代码:
int r[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (int j = 0; j < sizeof(r)/sizeof(r[0]); j++) {
int i = r[j];
if (i == 5)
i += 3;
}
So modifying iin the loop does not have the effect you expect.
所以i在循环中修改并没有你期望的效果。
Disassembly example
拆卸示例
You can look at the disassembly of the python codeto see this:
>>> from dis import dis
>>> def foo():
... for i in range (0,10):
... if i==5:
... i+=3
... print i
...
>>> dis(foo)
2 0 SETUP_LOOP 53 (to 56)
3 LOAD_GLOBAL 0 (range)
6 LOAD_CONST 1 (0)
9 LOAD_CONST 2 (10)
12 CALL_FUNCTION 2
15 GET_ITER
>> 16 FOR_ITER 36 (to 55)
19 STORE_FAST 0 (i)
3 22 LOAD_FAST 0 (i)
25 LOAD_CONST 3 (5)
28 COMPARE_OP 2 (==)
31 POP_JUMP_IF_FALSE 47
4 34 LOAD_FAST 0 (i)
37 LOAD_CONST 4 (3)
40 INPLACE_ADD
41 STORE_FAST 0 (i)
44 JUMP_FORWARD 0 (to 47)
5 >> 47 LOAD_FAST 0 (i)
50 PRINT_ITEM
51 PRINT_NEWLINE
52 JUMP_ABSOLUTE 16
>> 55 POP_BLOCK
>> 56 LOAD_CONST 0 (None)
59 RETURN_VALUE
>>>
This part creates a range between 0 and 10and realizes it:
这部分创建0到10之间的范围并实现它:
3 LOAD_GLOBAL 0 (range)
6 LOAD_CONST 1 (0)
9 LOAD_CONST 2 (10)
12 CALL_FUNCTION 2
At this point, the top of the stack contains the range.
此时,栈顶包含范围。
This gets an iterator over the object on the top of the stack, i.e. the range:
这在堆栈顶部的对象上获取迭代器,即范围:
15 GET_ITER
At this point, the top of the stack contains an iterator over the realized range.
此时,堆栈顶部包含一个在实现范围内的迭代器。
FOR_ITER begins iterating over the loopusing the iterator at the top of th estack:
FOR_ITER 开始使用 estack 顶部的迭代器遍历循环:
>> 16 FOR_ITER 36 (to 55)
At this point, the top of the stack contains the next value of the iterator.
此时,栈顶包含迭代器的下一个值。
And here you can see that the top of the stack is popped and assigned to i:
在这里你可以看到堆栈的顶部被弹出并分配给i:
19 STORE_FAST 0 (i)
So iwill be overwritten regardless of what you do in the loop.
i不管你在循环中做什么,所以都会被覆盖。
Here is an overview of stack machinesif you haven't seen this before.
回答by eyquem
it = iter(xrange (0,10))
for i in it:
if i==4: all(it.next() for a in xrange(3))
print i
or
或者
it = iter(xrange (0,10))
itn = it.next
for i in it:
if i==4: all(itn() for a in xrange(3))
print i
回答by AdityaS
In my view, the analogous code is not a while loop, but a for loop where you edit the list during runtime:
在我看来,类似的代码不是 while 循环,而是在运行时编辑列表的 for 循环:
originalLoopRange = 5
loopList = list(range(originalLoopRange))
timesThroughLoop = 0
for loopIndex in loopList:
print(timesThroughLoop, "count")
if loopIndex == 2:
loopList.pop(3)
print(loopList)
print(loopIndex)
timesThroughLoop += 1
回答by CopyPasteIt
You can make the following modification to your forloop:
您可以对for循环进行以下修改:
for i in range (0,10):
if i in [5, 6, 7]:
continue
print(i)
回答by pranav dua
In python 2.7 range function create a list while in python 3.x versions it creates a 'range' class object which is only iterable not a list, similar to xrange in python 2.7.
在python 2.7 range函数中创建一个列表,而在python 3.x版本中它创建一个'range'类对象,它只能迭代而不是一个列表,类似于python 2.7中的xrange。
Not when you are iterating over range(1, 10), eventually you are reading from the list type object and i takes new value each time it reaches for loop.
不是当您在 range(1, 10) 上迭代时,最终您是从列表类型对象中读取数据,并且每次到达 for 循环时 i 都会获取新值。
this is something like:
这类似于:
for i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
if i==5:
i+=3
print(i)
Changing the value wont change the iteration order from the list.
更改值不会更改列表中的迭代顺序。

