Closures in a loop
What does this print?
funcs = []
for i in range(3):
funcs.append(lambda x: x * i)
print([f(10) for f in funcs])
# [20, 20, 20]The lambdas do not capture the value of i. They capture the variable. By the time they are called, the loop has finished and i is 2 for all of them. This is called late binding.
Two fixes
- Bind the current value as a default argument, which is evaluated right when the function is created.
- Call a factory function, so each closure gets its own variable.
def times(n):
return lambda x: x * nComprehensions behave the same way, since each lambda still looks up the name when called.
Your task
Fix make_multipliers(n) so it returns a list of n functions where the function at position i multiplies its argument by i.
The explanation opens here once every check passes.