在for循环Python变量范围在for循环Python变量范围(Scope of python v

2019-05-06 11:38发布

继承人的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循环和最新的补救措施,它得到预期的输出。

Answer 1:

的用于通过在所有数字循环迭代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


Answer 2:

比喻用C代码

您想象你的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会不管你在循环做覆盖。

下面是一个堆栈机器的概述 ,如果你以前没有见过这个。



Answer 3:

一种在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


Answer 4:

如果由于某种原因你是真的想改变加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


Answer 5:

我得到复位每次迭代,所以它并没有真正不管你做什么它的循环中。 它没有做任何事情唯一的一次,当我是5,而它则增加了3到它。 一旦循环回它,然后将我背到列表中的下一个号码。 你可能想使用while在这里。



Answer 6:

Python的for循环循环遍历值的序列提供的-把它看成“的foreach”。 出于这个原因,修改变量对循环执行没有影响。

这被充分描述的教程 。



Answer 7:

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


Answer 8:

在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)

更改值不会改变从列表中的迭代顺序。



Answer 9:

在我看来,类似的代码是不是一个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


Answer 10:

你可以进行以下修改您for循环:

for i in range (0,10):
    if i in [5, 6, 7]:
        continue
    print(i)


文章来源: Scope of python variable in for loop