Toxicantidote Python - Lambda in iterators

Power status

Source: Local power
Generation sources
 100%Solar

Python - Lambda in iterators

March 2021

Recently I was working on a Python program and was encountering an issue using the lambda function inside of a loop. Essentially, the code was supposed to iterate through a list, and create a list of anonymous (lambda) functions based on that list.

A simplified original example is below:


data = [[1, 'a'], [2, 'b'], [3, 'c']]
functions = []

for number, letter in data:
    functions.append(lambda: print(str(number) + ' ' + letter))

for f in functions:
    f()

In the example above, I would have expected the program to print out:


1 a
2 b
3 c

But instead, it prints:


3 c
3 c
3 c

Odd, but not unreasonable when you work through it. It turns out that the anonymous function will only get the value of its arguments when it is executed, not when it is created. So, each new iteration of the first for loop changes the value of the arguments for all of the anonymous functions created.

Thankfully, the fix is easy. The lambda function lets you specify arguments which will have their value assigned when the function is created. To fix the above example, we simply change the code as below:


data = [[1, 'a'], [2, 'b'], [3, 'c']]
functions = []

for number, letter in data:
    functions.append(lambda n = number, l = letter: print(str(n) + ' ' + l))

for f in functions:
    f()

Now when we run the program, we see the expected output:


1 a
2 b
3 c