在python中的两个层循环中使用相同变量时发生了什么?

时间:2017-11-17 10:01:47

标签: python scope

我测试以下代码:

for i in range(3):
    for i in range(3,5):
        print "inner i: %d"%(i)
    print "outer i: %d"%(i)

,输出为:

inner i: 3
inner i: 4
outer i: 4
inner i: 3
inner i: 4
outer i: 4
inner i: 3
inner i: 4
outer i: 4

我不明白为什么在外环中i是4,但外环仍然运行3次。似乎i行中的变量print "outer i: %d"%(i)是内循环中的i,但是当转到for i in range(3)时,它在外循环中使用i。

任何人都可以解释这个吗?现在对我来说有点困惑。

6 个答案:

答案 0 :(得分:13)

它是相同的i,Python没有块范围。在每个for循环迭代开始时,将迭代器中的下一个值赋给i。 Python for循环不像C / Java for循环,它们是 foreach 循环。继续直到迭代器耗尽(或以某种方式break)。 for循环等效于以下while循环:

iterator = iter(my_iterable)
while True:
    try:
        x = next(iterator)
    except StopIteration:
        break
    do_stuff(x)

所以,你的嵌套循环相当于:

it1 = iter(range(3))
while True:
    try:
        i = next(it1)
    except StopIteration:
        break

    it2 = iter(range(3, 5))
    while True:
        try:
            i = next(it2)
        except StopIteration:
            break
        print "inner i: %d"%(i)

    print "outer i after: %d"%(i)

注意,C / Java for循环,例如:

for (int i = 0; i < stop; i++){
    do_stuff(i);
}

将使用Python:

i = 0
while i < stop:
   do_stuff(i)
   i += 1

换句话说,经典循环取决于i,也就是说,终止条件取决于i的值。但是在for-each循环中,终止条件取决于迭代器。无论你对身体内的变量做什么,在每次迭代开始时,都会为它分配迭代器的下一个值。

答案 1 :(得分:6)

在内部循环中,您为i分配了一个不同的变量。因为它是相同的变量,所以总是打印4(我在内循环中分配的最后一个值)。 但是,当你进入外循环的下一次迭代时,它将被设置为下一个值(即第二个外循环的2)。 您应该在内循环之前打印外循环以更清楚地看到效果:

for i in range(3):
    print "outer i before:%d"%(i)
    for i in range(3,5):
        print "inner i: %d"%(i)
    print "outer i after: %d"%(i)

答案 2 :(得分:3)

注意输出始终是

inner i: 3
inner i: 4
outer i: 4
每个外环都

程序在每次迭代中取最终值i

即。当外部循环开始执行时,i为0,1或2,但{for}循环中的i的值被修改。

更新

for i in range(3):
    for i in range(3,5):
        print (id(i))
    print (id(i))

输出

1372154016
1372154032
1372154032
1372154016
1372154032
1372154032
1372154016
1372154032
1372154032

答案 3 :(得分:2)

只有一个i,而不是两个i。当输入内部循环时,它会更改i,并不断更改它直到内部循环退出。外循环的下一次迭代然后将i设置为其范围中的下一个值,但是您永远不会看到它,因为您再次立即进入内循环,再次更改for

这当然是非常糟糕的做法。在该循环处于活动状态时,切勿在{{1​​}}循环中修改变量。

答案 4 :(得分:2)

它与我在两个循环中使用的相同。当外循环有机会打印i时,它将始终具有内循环的最后一个赋值。

答案 5 :(得分:1)

检查@heltonbiker回答:

>>> for i in range(3):
    print "1-",locals()
    for i in range(3,5):
        print "2-",locals()


1- {'__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'i': 0, '__name__': '__main__', '__doc__': None}
2- {'__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'i': 3, '__name__': '__main__', '__doc__': None}
2- {'__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'i': 4, '__name__': '__main__', '__doc__': None}
1- {'__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'i': 1, '__name__': '__main__', '__doc__': None}
2- {'__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'i': 3, '__name__': '__main__', '__doc__': None}
2- {'__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'i': 4, '__name__': '__main__', '__doc__': None}
1- {'__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'i': 2, '__name__': '__main__', '__doc__': None}
2- {'__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'i': 3, '__name__': '__main__', '__doc__': None}
2- {'__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'i': 4, '__name__': '__main__', '__doc__': None}
>>> 

您在错误的时间(地点)阅读i数据!

如果只有一个BUSVariable name您必须使用FIFO方法。

FIFO&lt;&lt;这里的信息