如何在循环中用lambda函数定义一个非常量函数列表?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在循环中用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 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 中是如何工作的。
你的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
工作就好了
以上是关于如何在循环中用lambda函数定义一个非常量函数列表?的主要内容,如果未能解决你的问题,请参考以下文章
Python单行函数lambda(小米)加reducemapfilter(步枪)应用