I'm trying to figure out what a line of code does but I'm struggling to understand how it works. I generally understand the purpose, use and limitations of lambda expressions in Python, but this line of code has me stumped and I couldn't find any other answers addressing it.
I'm trying to create multiple buttons for a calculator and when the button is pressed the corresponding value will appear. Rather than make 9 separate buttons, I wanted to use list comprehension to make them all at once (9 buttons, 1 for each number on the calculator). See code for more detail.
I don't really understand what x=button_num
is doing in the lambda x=button_num: enter_number(x)
expression and why it only works when it's written exactly this way. If I use the expression lambda: enter_number(button_num)
instead the calculator only shows the value 9, no matter which button I press.
# Function inserts value into calculator based on clicked button
def enter_number(x):
if entry_box.get() == "O": # Used to emulate that a calculator has a "0" initially
entry_box.delete(0, 'end')
entry_box.insert(0, str(x))
else:
length = len(entry_box.get())
entry_box.insert(length, str(x))
# Generate buttons
button_numbers = [Button(width=4, text=str(button_num), font='times 15 bold', bd=5,
command=lambda x=button_num: enter_number(x)) for button_num in range(10)]
To expand on Giovanni's answer, the reason that the other proposed method doesn't work is that lambda: enter_number(button_num)
will use the value of button_num
from the enclosing scope (ie the list comprehension). The value of button_num then changes for each subsequent lambda, and ends on 9. Ordinarily button_num
could be deleted at this point but since the lambda depend on it, it will stick around with its value of 9.
Default arguments, however, are evaluated at function definition time, not at function call time, so they won't fall prey to this problem. He's a more written out example
button_num = 0
def command(x=button_num):
print(x)
button_num = 1
command()
In the above code, command()
will print 0, not 1, since the value of button_num
was saved when it was used as a default argument.
lambda
is very similar to def
, but without the name. In both cases, something like x=10
defines a parameter named x
with a default value of 10
.
For example, consider this simple function.
def foo(x=10):
print("x: {}".format(x))
When run, you will get the following results:
foo()
prints "x: 10" foo(42)
=> prints "x: 42" lambda
is similar to a def (not exactly, but close enough for this discussion), except that the function is anonymous - it doesn't have a name. You can then assign this function to a variable, or pass it to something that is expecting to be passed a function such as when defining a callback.
For example, this creates an anonymous function and associates it with the variable named foo
. You can then call this exactly like you would any other function.
foo = lambda x=10: print("x: {}".format(x))
foo() # prints "x: 10"
foo(42) # prints "x: 42"
lambda
is a convenient way to create a function when you don't really care what the function name is, such as when creating callbacks. By using a default parameter, you are binding the current value of a variable as the default value of the given parameter.
As in a normal function definition, you can set a default value for the input of a lambda function
foo = lambda x=3: x+5
foo()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.