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

为何在列表推导式中包含完整lambda表达式?Python闭包解析

为什么要在列表推导式中用完整的lambda表达式解决闭包变量生命周期问题?

嘿,这个问题可是Python闭包里的经典“踩坑现场”,我来给你唠明白~

首先得先搞懂原代码为啥会出意外:

def create_multipliers():
    return [lambda x: i * x for i in range(5)]

for multiplier in create_multipliers():
    print(multiplier(2))

你以为会输出 0, 2, 4, 6, 8,结果全是 8?这是因为lambda里的i不是在创建时绑定值,而是在调用时才去查找变量i的当前值。列表推导式运行的时候,i在循环里从0跑到4,但所有lambda都共享同一个i的引用。等你后续调用这些lambda的时候,循环早就结束了,i已经固定成4了,所以每个lambda计算的都是4*2。

那为啥要在列表推导式里用“完整的lambda表达式”(也就是带默认参数的写法,比如lambda x, i=i: i*x)呢?

这是因为Python的函数默认参数是在函数定义时就完成求值绑定的,而不是调用时。当我们写lambda x, i=i: i*x的时候,每个lambda在创建的瞬间,都会把当时循环里i的当前值作为自己的默认参数存下来。这样每个lambda都持有了属于自己的i的“快照”,而不是共享那个会一直变化的外部变量i。

修正后的代码长这样:

def create_multipliers():
    return [lambda x, i=i: i * x for i in range(5)]

for multiplier in create_multipliers():
    print(multiplier(2))

运行这个代码,就能得到预期的0, 2, 4, 6, 8啦。

当然还有其他办法,比如用functools.partial来绑定参数,但用默认参数的lambda写法是最直接的原生解决方案,本质都是为了把循环变量的当前值固定在lambda创建的时刻,而不是等调用时才去取变量的最终值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:48:53