当外部循环和嵌套循环的范围都相同时,python中的for嵌套循环的行为如何?

当外部循环和嵌套循环的范围都相同时,python中的for嵌套循环的行为如何?,python,python-3.x,for-loop,Python,Python 3.x,For Loop,您能解释一下嵌套for循环在图1中的行为吗 x = 4 for j in range(x) for i in range(x) print(i) x = 2 图1 结果 0 1 2 3 0 1 0 1 0 1 我知道打印的前4个整数(0-3)是代码的结果 对于范围(x)内的j:代码,但为什么还打印以下内容 0 1 0 1 0 1 代码 x = 4 for j in range(x): print(i) x = 5 印刷品 0 1 2 3


您能解释一下嵌套for循环在图1中的行为吗

x = 4
for j in range(x)
   for i in range(x)
       print(i)
       x = 2
图1

结果

0
1
2
3
0
1
0
1
0
1
我知道打印的前4个整数(0-3)是代码的结果 对于范围(x)内的j:代码,但为什么还打印以下内容

0
1
0
1
0
1
代码

x = 4
for j in range(x):
    print(i)
    x = 5
印刷品

0
1
2
3
因此,显示在for循环中更改值x对迭代次数没有影响。range函数中的参数在循环的第一次迭代之前进行求值,而不是在后续迭代中进行重新求值

那么,对于图1中的嵌套循环,为什么x变为2

x = 4
for j in range(x)
   for i in range(x)
       print(i)
       x = 2
另一个类似的计划:

num_list = [1, 2, 3]
alpha_list = ['a', 'b', 'c']

for number in num_list:
    print(number)
    for letter in alpha_list:
        print(letter)
输出

1 #outer loop
a #nested loop
b #nested loop
c #nested loop
2 #outer loop
a #nested loop
b #nested loop
c #nested loop
3 #outer loop
a #nested loop
b #nested loop
c #nested loop
因此,我希望图1的输出是:

0 #outer loop
0 #Nested loop
1 #Nested loop
2 #Nested loop
3 #Nested loop
1 #outer loop
0 #Nested loop
1 #Nested loop
2 #Nested loop
3 #Nested loop
2 #outer loop
0 #Nested loop
1 #Nested loop
2 #Nested loop
3 #Nested loop
3 #outer loop
0 #Nested loop
1 #Nested loop
2 #Nested loop
3 #Nested loop

附加信息 Spyder中的Python 3.5

因此,显示在for循环中更改值x没有任何好处 对迭代次数的影响。范围中的参数 函数在循环的第一次迭代之前进行求值, 并且不会为后续迭代重新评估

那么,对于图1中的嵌套循环,为什么x变为2

x = 4
for j in range(x)
   for i in range(x)
       print(i)
       x = 2

不完全是。在第一个示例中,对于嵌套for循环,它确实会影响迭代次数。的确,一旦构建了
范围
对象,对用于构建该对象的任何变量进行更改都不会对
范围
对象产生影响-但是,在嵌套循环中,您不仅仅是创建了两个
范围
对象。您正在为外部循环创建一个对象,然后为外部循环的每个迭代的内部for循环创建一个新的
范围
对象。

您正在第二个
if
-语句中更改
x
的值

第一个
if
让我们运行第二个
if
4次。打印
0 1 2 3
一次后,您的
x
设置为2,再打印3次
0 1


由于第一个
如果
-
范围
迭代器已在运行,则更改的x不会受到影响。最好不要更改变量,您正在循环。

这是由于变量的范围。带有变量“i”的内部“for”循环中的x在内部“for”循环中优先。此变量x在内部“for”循环外部不可见,因此当您在外部“for”循环(使用变量“j”)中引用x时,它引用全局值4而不是2

希望这是有道理的


这不是一个很好的编码实践,尽量避免(如果可能的话)使用不同的变量名。

添加一些调试代码,看看会发生什么,让它更清晰

loops=1
x=4
对于范围(x)内的j:
打印(f'outer:j={j},x={x})
对于范围(x)内的i:
打印(f'inner:j={j},i={i},x={x})
印刷品(一)
x=2
打印(f'total loops{loops}')
循环+=1
输出:


    outer: j=0, x=4
    inner: j=0, i=0, x=4
    0
    total loops 1
    inner: j=0, i=1, x=2
    1
    total loops 2
    inner: j=0, i=2, x=2
    2
    total loops 3
    inner: j=0, i=3, x=2
    3
    total loops 4
    outer: j=1, x=2
    inner: j=1, i=0, x=2
    0
    total loops 5
    inner: j=1, i=1, x=2
    1
    total loops 6
    outer: j=2, x=2
    inner: j=2, i=0, x=2
    0
    total loops 7
    inner: j=2, i=1, x=2
    1
    total loops 8
    outer: j=3, x=2
    inner: j=3, i=0, x=2
    0
    total loops 9
    inner: j=3, i=1, x=2
    1
    total loops 10


很容易看出,一旦构建范围,设置
x
不会影响外循环迭代次数,但会改变内循环迭代次数。

[在此处输入图像描述][1]

x = 4
for j in range(x):
    print(i)
    x = 5
输出

0
1
2
3
请注意,上面的程序提出了一个问题:x的值是否会影响迭代次数。事实并非如此。在第一次迭代之前,对带有
for
行中
range
函数的参数进行求值

因此:

这是因为外部循环中的
range
功能只计算一次,而内部循环中的
range
功能在每次达到
for
的内部
状态时进行计算

注意:对于外部循环,范围在第一次迭代之前进行评估,对于
循环x=4,内部
。在外部
for
循环的第一次迭代结束时,内部
for
循环x=2,因为内部循环看不到初始x值

这是一个流程图,我想这有助于我理解


也许下面的代码可以解释它

您的第一个代码与此相同:

x=4
gen1=范围(x)#实际上等于范围(4)
对于gen1中的j:
gen2=范围(x)#这是第一次等于范围(4)。
#对于以下三次,这等于范围(2)。
对于gen2中的i:
印刷品(一)
x=2
请注意,
range(x)
创建并返回一个生成器对象,之后更改
x
不会改变该对象。但是每次都在
gen2=range(x)
行上创建一个全新的生成器对象,新值为
x