2016-11-22 83 views
1

我跑这块代码和输出是令人惊讶的。我知道我正在重复使用我,我的问题是为什么在我重新分配后的第一次迭代之后,循环没有退出!Python块范围 - 有人解释这

代码:

for i in range(3): 
    print '=====' 
    print 'Outer I: ', i 
    print '=====' 
    for j in range(2): 
     print 'J', j 
     for i in range(5): 
      print 'Inner I', i 
    print '=====' 
    print 'Outer I Again: ', i 
    print '=====' 

输出:

===== 
Outer I: 0 
===== 
J 0 
Inner I 0 
Inner I 1 
Inner I 2 
Inner I 3 
Inner I 4 
J 1 
Inner I 0 
Inner I 1 
Inner I 2 
Inner I 3 
Inner I 4 
===== 
Outer I Again: 4 
===== 
===== 
Outer I: 1 
===== 
J 0 
Inner I 0 
Inner I 1 
Inner I 2 
Inner I 3 
Inner I 4 
J 1 
Inner I 0 
Inner I 1 
Inner I 2 
Inner I 3 
Inner I 4 
===== 
Outer I Again: 4 
===== 
===== 
Outer I: 2 
===== 
J 0 
Inner I 0 
Inner I 1 
Inner I 2 
Inner I 3 
Inner I 4 
J 1 
Inner I 0 
Inner I 1 
Inner I 2 
Inner I 3 
Inner I 4 
===== 
Outer I Again: 4 

这里有事情是令人困惑:

  • 我希望循环到第一次迭代后破门,但它 才不是。
  • 出于同样的原因,第一个打印语句“Outer I” 会打印i的正确值。
  • 第二个外部打印语句 “外面的我再次”打印错误的值。

我在Python 2.7上用CPython运行这个。

+0

你的代码是错误的,你在内循环中重复使用'i'变量:'为我在范围内(5):' – EdChum

+0

做一件事,可能你会找到你想要的。用另一个变量** k **替换内部的i **。你会看到它会像魔术一样工作! ;) –

+1

Python中没有块范围。请参阅[范围规则简要说明](http://stackoverflow.com/questions/291978/short-description-of-scoping-rules)和[在Python中限制范围](http://stackoverflow.com/questions/6167923/block-scope-in​​-python) –

回答

3

在此代码中没有内部i或外部i,有一个单独的i变量分配在两个不同的循环中。 为什么在第一次迭代之后循环会中断? Python的for基本上是其他语言中的for each循环,它循环迭代器或给定生成器的成员。 range函数返回元素列表[0,1,2,3,4],并且每个迭代i被给出列表中的下一个值,当前值i对外部循环无关紧要。

这就是为什么第一个Outer I打印您期望的i值,但第二个(内循环后)不打印。

0

你重用i变量在你的内循环:

for i in range(5) 

所以你看:

Outer I Again: 4 

如果你把它变成一个不同的变量名字,那么它将按预期工作:

In [12]: 
for i in range(3): 
    print('=====') 
    print('Outer I: ', i) 
    print('=====') 
    for j in range(2): 
     print('J', j) 
     for l in range(5): 
      print('Inner I', l) 
    print('=====') 
    print('Outer I Again: ', i) 
    print('=====') 

===== 
Outer I: 0 
===== 
J 0 
Inner I 0 
Inner I 1 
Inner I 2 
Inner I 3 
Inner I 4 
J 1 
Inner I 0 
Inner I 1 
Inner I 2 
Inner I 3 
Inner I 4 
===== 
Outer I Again: 0 
===== 
===== 
Outer I: 1 
===== 
J 0 
Inner I 0 
Inner I 1 
Inner I 2 
Inner I 3 
Inner I 4 
J 1 
Inner I 0 
Inner I 1 
Inner I 2 
Inner I 3 
Inner I 4 
===== 
Outer I Again: 1 
===== 
===== 
Outer I: 2 
===== 
J 0 
Inner I 0 
Inner I 1 
Inner I 2 
Inner I 3 
Inner I 4 
J 1 
Inner I 0 
Inner I 1 
Inner I 2 
Inner I 3 
Inner I 4 
===== 
Outer I Again: 2 
===== 
0

您正在重复使用变量,但目标变量保持不变。在这种情况下,变量的范围不会随着里面的i而改变。为了处理像字符串或整数这样的不可变对象,你不会面临这个问题。使用一些其他变量,而不是第二个我,你会很好去。

+0

可变性与它无关 - 而实例* *实际上是用整数工作的,你指出它是不可变的。 –