2024-05-23 13:37:13 发布
网友
以下是python代码im遇到的问题:
for i in range (0,10): if i==5: i+=3 print i
我希望输出是:
0 1 2 3 4 8 9
然而,翻译说:
0 1 2 3 4 8 6 7 8 9
我知道一个for循环为C中的变量创建了一个新的作用域,但对python一无所知。有谁能解释一下为什么python中的i循环中的for值没有变化,以及如何补救它以获得预期的输出。
for
i
for循环遍历range(10)中的所有数字,即[0,1,2,3,4,5,6,7,8,9]。 改变i的当前值对范围内的下一个值没有影响。
range(10)
[0,1,2,3,4,5,6,7,8,9]
您可以通过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
Python中的for循环实际上是for-each循环。在每个循环的开始,将i设置为迭代器中的下一个元素(在您的示例中为range(0, 10))。i的值在每个循环开始时重新设置,因此在循环体中更改它不会更改下一次迭代的值。
range(0, 10)
也就是说,您编写的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
你在想象你在python中的for-loop是这样的C代码:
for-loop
for (int i = 0; i < 10; i++) if (i == 5) i += 3;
更像是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; }
因此,在循环中修改i不会产生预期的效果。
您可以查看disassembly of the python code来查看:
>>> 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 >>>
这一部分creates a range between 0 and 10并实现了它:
3 LOAD_GLOBAL 0 (range) 6 LOAD_CONST 1 (0) 9 LOAD_CONST 2 (10) 12 CALL_FUNCTION 2
此时,堆栈的顶部包含范围。
这个gets an iterator over the object on the top of the stack,即范围:
15 GET_ITER
此时,堆栈的顶部包含一个已实现范围上的迭代器。
FOR_ITER begins iterating over the loop使用位于堆栈顶部的迭代器:
>> 16 FOR_ITER 36 (to 55)
此时,堆栈顶部包含迭代器的下一个值。
在这里你可以看到the top of the stack is popped and assigned to ^{}:
19 STORE_FAST 0 (i)
因此无论您在循环中做什么,都将覆盖i。
这是一张overview of stack machines如果你以前没看过的话。
for循环遍历
range(10)
中的所有数字,即[0,1,2,3,4,5,6,7,8,9]
。改变
i
的当前值对范围内的下一个值没有影响。您可以通过while循环获得所需的行为。
Python中的for循环实际上是for-each循环。在每个循环的开始,将
i
设置为迭代器中的下一个元素(在您的示例中为range(0, 10)
)。i
的值在每个循环开始时重新设置,因此在循环体中更改它不会更改下一次迭代的值。也就是说,您编写的
for
循环相当于以下while循环:与C代码类似
你在想象你在python中的
for-loop
是这样的C代码:更像是C代码:
因此,在循环中修改
i
不会产生预期的效果。反汇编示例
您可以查看disassembly of the python code来查看:
这一部分creates a range between 0 and 10并实现了它:
此时,堆栈的顶部包含范围。
这个gets an iterator over the object on the top of the stack,即范围:
此时,堆栈的顶部包含一个已实现范围上的迭代器。
FOR_ITER begins iterating over the loop使用位于堆栈顶部的迭代器:
此时,堆栈顶部包含迭代器的下一个值。
在这里你可以看到the top of the stack is popped and assigned to ^{} :
因此无论您在循环中做什么,都将覆盖
i
。这是一张overview of stack machines如果你以前没看过的话。
相关问题 更多 >
编程相关推荐