Why do Python lambdas defined in a loop with different values all return the same result?


Before understanding why Python lambdas defined in a loop with different values all return the same result, let us first learn about Lambda.

Python Lambda

The Lambda expressions allow defining anonymous functions. A lambda function is an anonymous function i.e. a function without a name. Let us see the syntax −

lambda arguments: expressions

The keyword lambda defines a lambda function. A lambda expression contains one or more arguments, but it can have only one expression.

Example

Let us see an example

myStr = "Thisisit!" (lambda myStr : print(myStr))(myStr)

Output

Thisisit!

Python lambdas defined in a loop with different values all return the same result

Let us now understand why Python lambdas defined in a loop with different values all return the same result.

Let’s say we are finding the square. Use for loop to define a few different lambdas −

squares = [] for a in range(5): squares.append(lambda: a**2)

This gives you a list that contains 5 lambdas that calculate a**2. When called, they should return, 0, 1, 4, 9, and 16. However, actually they all return 16 as shown below −

squares = [] for a in range(5): squares.append(lambda: a**2) print(squares[2]())

Output

16

Now, try to run with some other value. It will give the same result −

squares = [] for a in range(5): squares.append(lambda: a**2) print(squares[4]())

Output

16

You got similar output because x is not local to the lambdas, but is defined in the outer scope, and it is accessed when the lambda is called i.e. not when it is defined.

At the end of the loop, the value of x is 4, therefore all the functions now return 4**2, i.e. 16. Verify this by changing the value of x and see how the output of the lambdas change −

squares = [] for a in range(5): squares.append(lambda: a**2) a = 8 print(squares[2]())

To avoid this, save the values in variables local to the lambdas, so they don’t rely on the value of the global a −

squares = [] for a in range(5): squares.append(lambda n=a: n**2)

Here, n=x creates a new variable n local to the lambda and computed when the lambda is defined so that it has the same value that a had at that point in the loop. This means the value of n will be 0 in the first lambda, 1 in the second, 2 in the third, and so on.

Therefore, each lambda will now return the correct result −

squares = [] for a in range(4): squares.append(lambda n=a: n**2) print(squares[2]())

Output

4

Let’s look at some other value −

squares = [] for a in range(5): squares.append(lambda n=a: n**2) print(squares[4]())

Output

16

Updated on: 19-Sep-2022

59 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements