如何在循环中用lambda函数定义一个非常量函数列表?

问题描述 投票:0回答:2

比方说,我想创建一个函数列表 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 FAQ). 例如,下面的语法就不能用。

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函数来实现这一结果吗?或者说,我有一个 "移动参数 "的事实注定了我必须以某种方式定义一个两个变量的函数?让我准确地说,我问这个问题是因为我试图更好地理解函数和库里在 Python 中是如何工作的。

python function lambda currying
2个回答
1
投票

你的lambda方法不起作用,因为你在位置参数之前有一个关键字参数。只要像你在工作解决方案中那样翻转顺序就可以了。

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

>>> funclist[3](8)
24
>>> funclist[5](9)
45

1
投票

最初的问题是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

工作就好了

© www.soinside.com 2019 - 2024. All rights reserved.