继承人的Python代码即时通讯有问题:
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变量的新的范围,但没有关于蟒蛇的想法。 任何人都可以解释为什么的价值i
犯规的改变for
在python循环和最新的补救措施,它得到预期的输出。
继承人的Python代码即时通讯有问题:
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变量的新的范围,但没有关于蟒蛇的想法。 任何人都可以解释为什么的价值i
犯规的改变for
在python循环和最新的补救措施,它得到预期的输出。
的用于通过在所有数字循环迭代range(10)
即, [0,1,2,3,4,5,6,7,8,9]
您更改当前值的i
,对范围内的下一个值没有影响。
你可以使用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
您想象你的for-loop
中的蟒蛇是这样的C代码:
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
在循环没有达到预期的效果。
你可以看看的Python代码的反汇编 ,看看这个:
>>> 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
>>>
这部分产生0和10之间的范围内 ,实现它:
3 LOAD_GLOBAL 0 (range)
6 LOAD_CONST 1 (0)
9 LOAD_CONST 2 (10)
12 CALL_FUNCTION 2
在这一点上,堆栈的顶部包含范围。
这个越过在堆栈的顶部的对象的迭代 ,即,范围:
15 GET_ITER
此时,堆叠的顶部包含在实现范围的迭代器。
FOR_ITER开始在迭代循环使用迭代器在第estack的顶部:
>> 16 FOR_ITER 36 (to 55)
在这一点上,堆栈的顶部包含迭代器的下一个值。
在这里你可以看到堆栈的顶部弹出并分配给i
:
19 STORE_FAST 0 (i)
所以, i
会不管你在循环做覆盖。
下面是一个堆栈机器的概述 ,如果你以前没有见过这个。
一种在Python循环实际上是一个for-each循环。 在每个循环的开始时, i
被设置为在迭代器(下一个元素range(0, 10)
你的情况)。 值i
被重新设置在每个循环的开始,所以在循环体中改变它不会改变它的下一个迭代值。
也就是说, 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
如果由于某种原因你是真的想改变加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
我得到复位每次迭代,所以它并没有真正不管你做什么它的循环中。 它没有做任何事情唯一的一次,当我是5,而它则增加了3到它。 一旦循环回它,然后将我背到列表中的下一个号码。 你可能想使用while
在这里。
Python的for
循环循环遍历值的序列提供的-把它看成“的foreach”。 出于这个原因,修改变量对循环执行没有影响。
这被充分描述的教程 。
it = iter(xrange (0,10))
for i in it:
if i==4: all(it.next() for a in xrange(3))
print i
要么
it = iter(xrange (0,10))
itn = it.next
for i in it:
if i==4: all(itn() for a in xrange(3))
print i
在Python 2.7版的功能范围内创建列表,而在Python 3.X版本中,它会创建一个“范围”类对象,它是唯一可迭代不是列表,类似在Python 2.7 XRANGE。
不是当你迭代范围(1,10),最终你从列表类型对象中读取并且每个到达for循环时间i取新的值。
这是一样的东西:
for i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
if i==5:
i+=3
print(i)
更改值不会改变从列表中的迭代顺序。
在我看来,类似的代码是不是一个while循环,而是一个循环,你在运行时编辑列表:
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
你可以进行以下修改您for
循环:
for i in range (0,10):
if i in [5, 6, 7]:
continue
print(i)