I'm working with python and trying to isolate a problem I had with lambda functions.
From the following code I was expecting to create two lambda functions, each getting a different x, and the output should be
1
2
but the output is
2
2
Why? And how can I make two different functions? Using def?
def main():
d = {}
for x in [1,2]:
d[x] = lambda: print(x)
d[1]()
d[2]()
if __name__ == '__main__':
main()
A lambda function can take any number of arguments, but can only have one expression.
A lambda function is an anonymous function (i.e., defined without a name) that can take any number of arguments but, unlike normal functions, evaluates and returns only one expression.
Since a for loop is a statement (as is print , in Python 2. x), you cannot include it in a lambda expression. Instead, you need to use the write method on sys.
A Python lambda function behaves like a normal function in regard to arguments. Therefore, a lambda parameter can be initialized with a default value: the parameter n takes the outer n as a default value. The Python lambda function could have been written as lambda x=n: print(x) and have the same result.
The body of the lambda
in your code references the name x
. The value associated with that name is changed on the next iteration of the loop, so when the lambda is called and it resolves the name it obtains the new value.
To achieve the result you expected, bind the value of x
in the loop to a parameter of the lambda
and then reference that parameter, as shown below:
def main():
d = {}
for x in [1,2]:
d[x] = lambda x=x: print(x)
d[1]()
d[2]()
if __name__ == '__main__':
main()
>>>
1
2
Looks like work for partial
.
from functools import partial
def main():
d = {}
for x in [1,2]:
d[x] = partial(lambda x: print(x), x=x)
d[1]()
d[2]()
if __name__ == '__main__':
main()
This will fix it. It is because the x is directly bound to the lambda.
def create_lambda(x):
return lambda : print(x)
def main():
d = {}
for x in [1,2]:
d[x] = create_lambda(x)
d[1]()
d[2]()
if __name__ == '__main__':
main()
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