我刚刚从 Matlab 切换到 Python,我想使用 lambda 函数将具有多个参数的函数
f1(x,y)
映射到一个参数函数 f2(x)
进行优化。
我希望当我映射函数f2(x) <- f1(x,y=y1)
时,无论y
发生什么变化,y1
都将保持不变,在Matlab中默认情况下这是正确的,但如果我在Python中尝试,它会不断变化,如下例所示
>>> def f1(x,y):
>>> return (x+y)
>>> y1 = 2
>>> f2 = lambda x: f1(x,y1)
>>> f2(1)
3
我希望即使我改变
f2(1)
,3
仍然是y1
,但是如果我改变y1
,整个f1(1)
也会改变如下
>>> y1 = 5
>>> f2(1)
6
我想知道有没有一种方法,当我声明
f2 = lambda x: f1(x,y1)
时,f1
将采用当时y1
的值并将其固定为f2
。这样做的原因是因为我想为不同的场景动态创建不同的函数,然后将它们全部相加。
我对Python还是个新手,请帮助,非常感谢。
尝试:
f2 = lambda x, y=y1: f1(x,y)
你的问题与闭包在Python中如何工作
有关您的 lambda 函数版本将使用当前版本的
y1
。 您需要在定义 lambda 函数的行上捕获 y1
的值。 为此,您可以将其定义为参数的默认值(y=y1
部分)。
正如已经指出的,您的问题归结为闭包如何工作。但是,您确实不应该为此使用 lambda - lambda 用于匿名函数。用
def
语句代替创建高阶函数:
>>> def f1(x,y):
... return x + y
...
>>> def f1_factory(y):
... def f1_y(x):
... return f1(x,y)
... return f1_y
...
>>> f1_factory(6)(4)
10
>>> f1_factory(5)(4)
9
也避免了您遇到的问题:
>>> y = 3
>>> newfunc = f1_factory(y)
>>> newfunc(1)
4
>>> y = 20
>>> newfunc(1)
4
>>>
来自PEP8:
始终使用 def 语句而不是赋值语句 将 lambda 表达式直接绑定到标识符。
是的:
def f(x): 返回 2*x
否:
f = lambda x: 2*x
第一种形式表示结果的名称 函数对象具体是“f”,而不是通用的
。 这对于回溯和字符串表示更有用 一般的。赋值语句的使用消除了唯一的 与显式 def 语句相比,lambda 表达式可以提供的好处 (即它可以嵌入到更大的表达式中)<lambda>
functools.partial
。对于你的情况:
>>> from functools import partial
>>> def f1(x,y):
>>> return (x+y)
>>> y1 = 2
>>> f2 = partial(f1, y=y1)
>>> f2(1)
3
>>> y1 = 5
>>> f2(1)
3