python for 循环中的作用域:为什么索引会减少

scope in python for loop: why does index decrease

出于好奇,我想看看

会发生什么
x=4
y=3
for y in xrange(0,y):
    print "Y---",y
    print "X---",x
    for x in xrange(0,x):
        print "x",x

这会打印出来

Y--- 0
X--- 4 

x 0
x 1
x 2
x 3

Y--- 1
X--- 3 

x 0
x 1
x 2

Y--- 2
X--- 2 

x 0
x 1

y 按预期进展,但 x 减少 - 是什么导致这种情况发生?

您的变量 x = 4 引用第二个 for 循环中的 x 变量,即 for x in xrange(0,x):,它们都在模块级范围内。因此,在内部循环的每次迭代之后,x 都会被赋予一个新值。

例如:

>>> x = 4
>>> for x in xrange(0, 2):
...     print x
...
0
1
>>> x
1

您的内循环重新定义了 x,因此每个外循环都会使它使用 x 的最后一个新的较小值。这使得内部循环每次都更短。

发生这种情况是因为您将 x 既用作要迭代的范围的输入,又用作循环的实际计数器。 x 保留作为内部循环的一部分给它的最后一个值,并且 xrange 的性质是 x-1.

要查看发生了什么,请尝试:

x = 10
for x in xrange(5):
    print x
print x

最终输出为 4,因为这是 x 在 for 循环中采用的最后一个值。

如果您不希望出现这种情况,请使用另一个变量作为内循环的计数器。即

x=4
y=3
for y in xrange(0,y):
    print "Y---",y
    print "X---",x
    for z in xrange(0,x):
        print "x",z

与其他一些语言不同,Python 循环不会引入新的作用域。这意味着使用 x 作为循环变量不会像您期望的那样隐藏全局 x - 相反,它会被重新分配。您可以通过在循环后执行 print x 来看到这一点 - 它不会恢复到其循环前的值,但会保留上次迭代时的值。这也将是它将在外循环的下一次迭代中保留的值。通过使用在循环之前不存在的循环变量,您可以更清楚地看到同样的事情:如果循环创建了一个新范围,则尝试打印该变量将是一个 NameError,但事实并非如此。