You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python嵌套循环变量作用域疑问:为何内层循环会覆盖外层变量?

为什么Python循环变量会被内层循环覆盖?

这是个非常典型的Python作用域问题——没错,Python确实不遵循Java/C那样的块级作用域规则,这也是很多从静态语言转Python的开发者容易踩的坑。

先帮你把代码整理成更易读的格式(你的原始代码因为缩进问题,实际执行结构是这样的):

def temp():
    temparray = ['a','b']
    temparray_2 = ['c','d','e']
    for i in temparray:
        print('i:' + str(i))
        for i in temparray_2:
            print('first: ' + str(i))
        print('Second: ' + str(i))
    print('final: ' + str(i))

核心原因:Python没有块级作用域

在Java或C里,每个{}代码块都会创建独立的作用域,循环变量i会被限制在循环块内部,内层循环的i和外层的i是完全不同的变量。但Python的作用域是基于函数、类、模块这三级的,普通的循环、条件判断块(比如for/if)并不会创建新的作用域——也就是说,你在外层循环定义的i,和内层循环用的i是同一个变量!

逐行分析你的输出逻辑

  1. 进入外层循环,第一次迭代i = 'a',先输出i:a
  2. 进入内层循环,此时i被重新赋值为temparray_2的元素:
    • 第一次内层迭代:i='c',输出first: c
    • 第二次内层迭代:i='d',输出first: d
    • 第三次内层迭代:i='e',输出first: e
  3. 内层循环结束,i的值停留在最后一个元素'e',所以执行print('Second: ' + str(i))时,输出Second: e
  4. 外层循环进入第二次迭代,i被重新赋值为'b',输出i:b
  5. 重复内层循环的过程,i再次被覆盖为'e',输出first: c/first: d/first: e后,执行print('Second: ' + str(i))输出Second: e
  6. 外层循环结束,i的值还是最后一次内层循环的'e',所以最后的print('final: ' + str(i))输出final: e

怎么避免这种问题?

最简单的办法就是内层循环用不同的变量名,比如把内层的i改成j

def temp():
    temparray = ['a','b']
    temparray_2 = ['c','d','e']
    for i in temparray:
        print('i:' + str(i))
        for j in temparray_2:
            print('first: ' + str(j))
        print('Second: ' + str(i))
    print('final: ' + str(i))

这样内层循环的变量就不会干扰外层的i,输出就符合预期了。

内容的提问来源于stack exchange,提问作者Ted

火山引擎 最新活动