Considering the following code snippet:
# directorys == {'login': <object at ...>, 'home': <object at ...>} for d in directorys: self.command["cd " + d] = (lambda : self.root.change_directory(d))
I expect to create a dictionary of two function as following :
# Expected : self.command == { "cd login": lambda: self.root.change_directory("login"), "cd home": lambda: self.root.change_directory("home") }
but it looks like the two lambda function generated are exactly the same :
# Result : self.command == { "cd login": lambda: self.root.change_directory("login"), "cd home": lambda: self.root.change_directory("login") # <- Why login ? }
I really don't understand why. Do you have any suggestions ?
Since a for loop is a statement (as is print , in Python 2. x), you cannot include it in a lambda expression.
That's not more than one return, it's not even a single return with multiple values. It's one return with one value (which happens to be a tuple).
Lambda functions can only have one expression in their body. Regular functions can have multiple expressions and statements in their body.
Lambda functions does not allow multiple statements, however, we can create two lambda functions and then call the other lambda function as a parameter to the first function.
You need to bind d for each function created. One way to do that is to pass it as a parameter with a default value:
lambda d=d: self.root.change_directory(d)
Now the d inside the function uses the parameter, even though it has the same name, and the default value for that is evaluated when the function is created. To help you see this:
lambda bound_d=d: self.root.change_directory(bound_d)
Remember how default values work, such as for mutable objects like lists and dicts, because you are binding an object.
This idiom of parameters with default values is common enough, but may fail if you introspect function parameters and determine what to do based on their presence. You can avoid the parameter with another closure:
(lambda d=d: lambda: self.root.change_directory(d))() # or (lambda d: lambda: self.root.change_directory(d))(d)
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