简体   繁体   English

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

[英]How to define a list of non-constant functions in a loop with lambda functions?

Let's say that I want to create a list of functions funclist , such that the fonctions of this list behave that way:假设我想创建一个函数列表funclist ,这样该列表的函数就会以这种方式运行:

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

Assuming that the list is too long (say of size 100) to define those functions one-by-one, a natural way to write this would be:假设列表太长(例如大小为 100)而无法逐个定义这些函数,那么自然的编写方法是:

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

The problem is that this approach does not work, because of the way Python interprets local variables within function definitions.问题是这种方法不起作用,因为 Python 解释 function 定义中的局部变量的方式。 This is a problem I saw coming back often on this website, for instance here or here .这是我在这个网站上经常看到的一个问题,例如这里这里 Unfortunately, those users want to define constant functions, so the proposed solution (which is to define a local copy of the iterable variable k) do not work for me (it is also the same solution proposed in the Python FAQ ).不幸的是,这些用户想要定义常量函数,因此建议的解决方案(即定义可迭代变量 k 的本地副本)对我不起作用(这也是Python 常见问题解答中提出的相同解决方案)。 For instance, the following syntax does not work:例如,以下语法不起作用:

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

A solution I found is to do:我找到的解决方案是:

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

which works as I want.可以按我的意愿工作。 I could also achieve the same result with the partial function:我也可以使用partial function 实现相同的结果:

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) )

So my question is: is there any way to achieve this result with lambda functions only?所以我的问题是:有什么方法可以仅使用 lambda 函数来实现此结果? Or the fact that I have a "moving parameter" dooms me to define in a way or an other a function of two variables?或者我有一个“移动参数”这一事实注定我要以某种方式或其他方式定义两个变量的 function? Let me precise that I am asking this because I am trying to understand better how functions and currying work in Python.让我准确地说我问这个是因为我想更好地理解函数和柯里化在 Python 中是如何工作的。

Your lambda approach does not work because you have a keyword argument before a positional one.您的 lambda 方法不起作用,因为您在位置参数之前有一个关键字参数。 Just flip the order as you did in the working solutions:只需像在工作解决方案中那样翻转顺序:

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

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

The initial problem is that k was only evaluated one time, at the end of the loop, while here the function creation, the call to get_function, triggers the evaluation of k every time.最初的问题是 k 只被评估了一次,在循环结束时,而这里 function 创建,对 get_function 的调用,每次都会触发对 k 的评估。

Of course your solution with a default argument also works, it's apparently the most common solution for this problem当然,您使用默认参数的解决方案也可以,这显然是解决此问题的最常见解决方案

Now you said it didn't work with the lamdba, it's simply because you put the default argument first:现在您说它不适用于 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

works just fine工作得很好

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM