如何让Lambda表达式独立于局部变量?解决for循环Lambda依赖问题
解决Python中for循环内lambda绑定循环变量的问题
问题本质
lambda表达式是延迟绑定外部变量的——直到调用lambda时,才会去读取变量的当前值,而不是定义lambda时的变量值。这就导致for循环里所有lambda都共享同一个循环变量,调用时全取到循环结束后的最终值。
解决方案
1. 利用默认参数捕获当前变量值
在lambda中添加默认参数,将当前循环的i值绑定到默认参数上。默认参数会在lambda定义时就完成求值,从而固定当时的变量值:
tmp = [] for i in range(5): tmp.append(lambda x, i=i: x + i) print(tmp[0](1)) # 输出1,符合预期 print(tmp[4](1)) # 输出5,符合预期
2. 用闭包(嵌套函数)隔离作用域
通过嵌套函数创建独立的作用域,每次循环时将当前i传入嵌套函数,让lambda引用该作用域内的局部变量:
tmp = [] def make_lambda(current_i): return lambda x: x + current_i for i in range(5): tmp.append(make_lambda(i)) print(tmp[0](1)) # 输出1 print(tmp[4](1)) # 输出5
3. 使用functools.partial绑定固定参数
借助functools.partial将循环变量作为固定参数绑定到lambda上,强制在定义阶段锁定变量值:
from functools import partial tmp = [] for i in range(5): tmp.append(partial(lambda x, val: x + val, val=i)) print(tmp[0](1)) # 输出1 print(tmp[4](1)) # 输出5
为什么eval(str(i))无效?
eval(str(i))是在lambda被调用时才执行的,此时循环已经结束,i的最终值是4(range(5)的最后一个元素),所以所有lambda调用时都会取到4,加1后输出5,无法解决问题。
内容的提问来源于stack exchange,提问作者disp
相关产品推荐
相关产品推荐

