如何在带有lambda函数的循环中定义一个非常量函数列表



假设我想创建一个函数funclist的列表,以便该列表中的函数以这种方式运行:

funclist[0](x) = 0
funclist[1](x) = x
funclist[2](x) = 2*x
funclist[3](x) = 3*x

假设列表太长(比如大小为100(,无法逐个定义这些函数,那么写这篇文章的自然方法是:

funclist = []
for k in range(100):
f = lambda x: k*x
funclist.append(f)

问题是,由于Python在函数定义中解释局部变量的方式,这种方法不起作用。这是我经常在这个网站上看到的一个问题,例如在这里或这里。不幸的是,这些用户想要定义常量函数,因此所提出的解决方案(即定义可迭代变量k的本地副本(对我不起作用(这也是Python常见问题解答中提出的相同解决方案(。例如,以下语法不起作用:

funclist = []
for k in range(100):
f = lambda local_k=k, x: local_k*x
funclist.append(f)

我找到了一个解决方案:

funclist = []
for k in range(10):
def f(x, product_factor=k): return x*product_factor
funclist.append(f)

它按我的意愿工作。我也可以通过partial功能获得相同的结果:

from functools import partial 
def product(x,product_factor): return x*product_factor
funclist = []
for k in range(10):
funclist.append( partial(product, product_factor=k) )

所以我的问题是:有没有办法只使用lambda函数来实现这个结果?或者,我有一个"移动参数"的事实注定了我要以某种方式或其他方式定义一个由两个变量组成的函数?让我确切地说,我之所以这么问,是因为我试图更好地理解函数和currying在Python中是如何工作的。

您的lambda方法不起作用,因为在位置参数之前有一个关键字参数。只需像在工作解决方案中那样翻转订单:

funclist = [(lambda x, local_k=k: local_k*x) for k in range(100)]
>>> funclist[3](8)
24
>>> funclist[5](9)
45

最初的问题是,在循环结束时,只对k求值一次,而在这里,函数创建,即对get_function的调用,每次都会触发对k的求值。

当然,你的默认参数的解决方案也有效,这显然是这个问题最常见的解决方案

现在你说它不适用于lamdba,这只是因为你把默认参数放在第一位:

funclist = []
for k in range(100):
f = lambda  x, local_k=k,: local_k*x
funclist.append(f)

print(funclist[10](3)) #30
print(funclist[99](3)) # 297
print(funclist[0](3)) # 0

运行良好

最新更新