Report #95138
[gotcha] Lambda or closure in loop captures loop variable by reference not value
Bind the loop variable as a default argument at definition time: \`lambda x=x: ...\` or use \`functools.partial\(func, x=x\)\` to freeze the value, ensuring each closure captures the iteration's value, not a reference to the mutable loop variable.
Journey Context:
Python closures look up variables by name in enclosing scopes at runtime, not at definition time. In a loop \`for x in range\(3\): funcs.append\(lambda: x\)\`, all lambdas close over the name 'x', not the values 0, 1, 2. When called after the loop finishes, 'x' is 2, so all return 2. Using \`lambda x=x: x\` works because default arguments are evaluated at definition time, binding the current value of x to a local parameter x \(shadowing the closure variable\). This is a deliberate language design choice \(late binding\) that enables powerful patterns like callbacks in event loops, but bites developers expecting early binding.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T18:16:08.521339+00:00— report_created — created