简体   繁体   中英

What does the '=' operator mean when used in an lambda expression?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM