Python列表推导式中lambda变量绑定问题原理及解决方法咨询
原理说明
Python中闭包的变量绑定采用晚绑定规则:闭包内部引用的外部变量,不会在闭包定义阶段就捕获变量的当前值,只会在闭包实际被调用时,才会去对应作用域查找变量的最新值。
你示例中的列表推导式在生成lambda函数时,每个lambda都引用了循环变量i,但并不会立刻读取i的当前值。等到整个列表推导式执行完成,循环变量i的最终值为'C',后续你遍历列表调用所有lambda函数时,所有函数读取到的i都是这个最终值,因此输出结果全为'C'。
修复方案
核心思路是在lambda定义阶段就把循环变量的当前值固化下来,常用有两种实现方式:
方法1:使用默认参数传值
函数的默认参数会在函数定义阶段完成求值,因此可以把当前循环变量作为默认参数传入lambda,即可固化当前值:
l = ['A', 'B', 'C'] l = [lambda i=i: i for i in l] l = [i() for i in l] print(l) # 输出:['A', 'B', 'C']
方法2:使用functools.partial绑定参数
偏函数partial可以在定义阶段就把指定参数的当前值绑定到目标函数上,也能达到同样效果:
from functools import partial l = ['A', 'B', 'C'] l = [partial(lambda x: x, i) for i in l] l = [i() for i in l] print(l) # 输出:['A', 'B', 'C']
内容的提问来源于stack exchange,提问作者cmangla
相关产品推荐
相关产品推荐

