另一个函数的 lambda 函数,但强制固定参数

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

我刚刚从 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还是个新手,请帮助,非常感谢。

python function lambda
3个回答
13
投票

尝试:

f2 = lambda x, y=y1: f1(x,y)

你的问题与闭包在Python中如何工作

有关

您的 lambda 函数版本将使用当前版本的

y1
。 您需要在定义 lambda 函数的行上捕获
y1
的值。 为此,您可以将其定义为参数的默认值(
y=y1
部分)。


1
投票

正如已经指出的,您的问题归结为闭包如何工作。但是,您确实不应该为此使用 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”,而不是通用的

<lambda>
。 这对于回溯和字符串表示更有用 一般的。赋值语句的使用消除了唯一的 与显式 def 语句相比,lambda 表达式可以提供的好处 (即它可以嵌入到更大的表达式中)


0
投票

最优雅和现代的解决方案是使用

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
© www.soinside.com 2019 - 2024. All rights reserved.