I just switched to Python from Matlab, and I want to use lambda function to map function f1(x,y)
with multiple arguments to one argument function f2(x)
for optimization.
I want that when I map the function f2(x) <- f1(x,y=y1)
then y
will stay constant no matter what y1
changes, in Matlab this is true by default but if I try in Python, it keeps changing as the following examples
>>> def f1(x,y):
>>> return (x+y)
>>> y1 = 2
>>> f2 = lambda x: f1(x,y1)
>>> f2(1)
3
I expect f2(1)
stays 3
even if I change y1
, however if I change y1
, the whole f1(1)
also changes as follows
>>> y1 = 5
>>> f2(1)
6
I wonder is there a way that when I declare f2 = lambda x: f1(x,y1)
then f1
will take the value of y1
at that time and fix it to f2
. The reason for this because I want to dynamically create different functions for different scenarios then sum them all.
I'm still new to Python, please help, much appreciate.
Try:
f2 = lambda x, y=y1: f1(x,y)
Your issue has to do with how closures work in Python
Your version of the lambda function will use the current version of y1
. You need to capture the value of y1
on the line where you've defined the lambda function. To do that, you can define it as the default value of a parameter (the y=y1
part).
As already pointed out, your issue comes down to how closures work. However, you really shouldn't be using a lambda for this - lambdas are for anonymous functions. Make a higher-order function with def
statements instead:
>>> 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
It also avoids the problem you encountered:
>>> y = 3
>>> newfunc = f1_factory(y)
>>> newfunc(1)
4
>>> y = 20
>>> newfunc(1)
4
>>>
From PEP8:
Always use a def statement instead of an assignment statement that binds a lambda expression directly to an identifier.
Yes:
def f(x): return 2*x
No:
f = lambda x: 2*x
The first form means that the name of the resulting function object is specifically 'f' instead of the generic
<lambda>
. This is more useful for tracebacks and string representations in general. The use of the assignment statement eliminates the sole benefit a lambda expression can offer over an explicit def statement (i.e. that it can be embedded inside a larger expression)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With