What does this print?
fns = [lambda: i for i in range(3)]
print([f() for f in fns])Options
- [0, 1, 2]
- [2, 2, 2] (Correct option)
- [3, 3, 3]
- NameError
Answer
[2, 2, 2]
Why
Each lambda does NOT save the value of i when it is created. It saves a link to the variable i and reads it later, when it is called (this is called late binding).
When we call the lambdas, the loop has already finished and i is 2, so all of them return 2.
Fix: capture the current value as a default argument, which is evaluated immediately.
fns = [lambda i=i: i for i in range(3)] # [0, 1, 2]Remember
Closures remember variables, not values.