Late-binding closures: the classic loop-variable-capture bug
A closure captures the variable, not its value at closure-creation time. Since Python's for loop reuses
the same variable name on every iteration, every lambda created inside the loop shares that one variable —
and by the time any of them actually runs, the loop has already finished and the variable holds its final
value. This bites nearly everyone at least once, especially building lists of callbacks.
funcs = [lambda: i for i in range(3)]
print("naive:", [f() for f in funcs], " <- all see the FINAL value of i (2), not 0,1,2")
funcs_fixed = [lambda i=i: i for i in range(3)]
print("fixed via default-arg capture:", [f() for f in funcs_fixed])
def make_fn(i):
return lambda: i
funcs_fixed2 = [make_fn(i) for i in range(3)]
print("fixed via factory function: ", [f() for f in funcs_fixed2])