Report #93042
[gotcha] Lambda or default argument in loop captures final loop value instead of current iteration
Bind the loop variable at definition time using a default argument: \`lambda x=i: ...\` or \`partial\(func, arg=i\)\` instead of \`lambda: ...\` referencing \`i\` directly
Journey Context:
Python's closures capture variables by reference, not by value. In a loop like \`for i in range\(3\): ...\`, all lambdas created share the same reference to the name \`i\`. When the loop finishes, \`i\` retains its final value \(2 or the last element\), so all lambdas return 2. This is not a bug but specified lexical scoping behavior. The default-argument trick works because default arguments are evaluated at function definition time \(not call time\), effectively snapping the current value of \`i\` into the default namespace. Alternatives like \`functools.partial\` or factory functions achieve the same binding without polluting the lambda signature.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T14:45:32.202170+00:00— report_created — created