如何让Python按值传递变量?解决函数列表绑定异常问题
解决Python循环中Lambda绑定引用而非值的问题
你说得完全对——Python里的lambda(以及所有闭包函数)在循环中绑定的是变量的引用,而不是循环迭代时的当前值。当循环结束时,变量i的值已经变成了9,所以所有lambda调用时都会用这个最终值,导致输出全是9。
下面给你几种简单有效的解决方法,都能让每个函数捕获到迭代时i的具体数值:
方法1:给Lambda添加默认参数(最简洁)
利用Python默认参数在函数定义时求值的特性,把当前的i值绑定到一个新的参数上:
functions = [] for i in range(1,10): # 这里n=i会在每次循环时把当前i的数值赋值给n,而非保留引用 functions.append(lambda x, n=i : x + n) for f in functions: print(f(0), end=' ') # 输出:1 2 3 4 5 6 7 8 9
这样每个lambda都拥有了自己独立的n变量,存储的是循环迭代时i的具体值,而不是指向同一个i的引用。
方法2:使用functools.partial包装函数
如果你觉得lambda的写法不够直观,可以用functools.partial来创建偏函数,固定加法的第二个参数:
from functools import partial # 先定义一个基础的加法函数 def add(x, n): return x + n functions = [] for i in range(1,10): # 每次循环固定n为当前i的值,生成新的偏函数 functions.append(partial(add, n=i)) for f in functions: print(f(0), end=' ') # 输出正确结果
partial会帮你把指定参数固定下来,生成一个新的函数,每个新函数都持有自己的n值副本。
方法3:用内层函数捕获当前值
通过创建一个内层函数,让它接收当前的i值并返回对应的lambda,这样内层函数的参数会捕获迭代时的数值:
functions = [] for i in range(1,10): # 内层函数make_adder接收当前i作为n,返回绑定了n的lambda def make_adder(n): return lambda x: x + n functions.append(make_adder(i)) for f in functions: print(f(0), end=' ')
这种方式本质上和方法1类似,都是通过在函数定义时绑定具体值,避免后续引用循环变量的最终值。
总的来说,这三种方法的核心思路都是让每个函数在定义时就捕获到迭代时刻i的具体数值,而不是保留对循环变量i的引用。其中方法1是最常用也最简洁的写法。
内容的提问来源于stack exchange,提问作者blueocean
相关产品推荐
相关产品推荐

