Late-binding lambdas
What does this print? Most people expect [0, 1, 2]. Explain the real output and fix it.
funcs = [lambda: i for i in range(3)]
print([f() for f in funcs])
Show hint
A lambda does not copy i when it is created. It looks i up when it is called.
Show solution
# Prints:
# [2, 2, 2]
funcs = [lambda i=i: i for i in range(3)]
print([f() for f in funcs]) # [0, 1, 2]
All three lambdas refer to the same variable i. By the time any of them runs, the loop has finished and i is 2. This is called late binding, and it applies to functions defined with def inside loops too.
A default argument is evaluated when the lambda is created, so i=i captures the current value.
Want a problem like this every day? See today's problem and keep a streak going.