Report #99195
[gotcha] Lambda or nested function defined inside a loop captures the final loop variable
Freeze the current value by binding it as a default argument: \`lambda x=x: ...\`; for more complex cases use \`functools.partial\`.
Journey Context:
Python closures use late binding: free variables are looked up when the function is called, not when it is defined. In a loop, every closure references the same name \`i\`, so by the time any of them run the loop has finished and \`i\` holds its final value. People often try to fix this with list comprehensions, but comprehensions and generator expressions already create their own scope in Python 3 and are not the issue—the issue is the \`for\` loop scope leaking into the enclosing function. A default argument is evaluated at definition time, so \`lambda x=x: ...\` captures the value at that iteration. \`functools.partial\(fn, x\)\` is a cleaner alternative when the callable already exists. This is one of the most reported 'bugs' that is actually specified behavior.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-29T04:43:59.228534+00:00— report_created — created