You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中修改lambda调用处循环变量名为何导致执行结果变化?

问题复现

定义lambda函数的初始代码:

a = []
for i in range(3):
    a.append(lambda a:i+a)

第一种调用方式,循环变量使用j:

for j in range(3):
    print(a[j](0))

输出为三个2:

2
2
2

第二种调用方式,循环变量改用i,执行逻辑和前者完全一致:

for i in range(3):
    print(a[i](0))

输出为0、1、2:

0
1
2
根本原因

这个现象是两个Python语言特性共同作用的结果:

  • 闭包延迟绑定:lambda(包括普通def定义的函数)捕获外部变量时,存储的是变量的引用,不是定义瞬间的值。函数真正执行的时候,才会去当前作用域查找对应变量名的最新值。
    第一个调用场景里,定义完3个lambda后,外层作用域的循环变量i已经走完range(3)迭代,最终值固定为2。调用时的循环变量用的是j,不会修改外层的i,因此三个lambda执行时取到的i都是2,传入参数0时计算结果都是2+0=2,最终输出三个2。
  • for循环变量无块级作用域:Python不存在很多其他语言常见的块级作用域,for循环声明的循环变量会泄露到外层作用域,循环结束后变量依然存在,值为最后一轮的迭代结果。
    第二个调用场景里,循环变量名改成了i,这个i和之前定义lambda时外层作用域的i是同一个变量。循环执行过程中:
    • 第一轮迭代i=0,调用第一个lambda,此时查找到的i值为0,计算得0+0=0
    • 第二轮迭代i=1,调用第二个lambda,此时i已经被循环修改为1,计算得1+0=1
    • 第三轮迭代i=2,调用第三个lambda,此时i值为2,计算得2+0=2
      最终输出就是0、1、2。
修复方案

如果希望lambda在定义时就固定当时的i值,不受后续外部变量变动影响,可以把i作为lambda的默认参数传入——Python函数的默认参数是在函数定义时刻就完成求值绑定的:

a = []
for i in range(3):
    # 把i作为默认参数传入,定义时就固定对应值
    a.append(lambda a, i=i: i+a)

用这种写法后,无论调用时的循环变量叫什么名字,输出都会是预期的0、1、2。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 18:06:25