[Python-ideas] For loop binding (was Re: Tweaking closures ...)

Terry Reedy tjreedy at udel.edu
Tue Sep 27 23:10:27 CEST 2011

On 9/27/2011 1:05 AM, Greg Ewing wrote:
> For example, when someone writes
> for i in things:
>  def f():
>   dosomethingwith(i)
>  squirrelaway(f)
> and get surprised by the result,

People who post their 'surprise' on python-list have nearly always used 
lambda, not def, to define the function. This is so much the case that I 
have concluded that 'lambda' has a hypnotic effect that 'def' does not.

> he's effectively assuming that the for-loop creates a new binding for
> i each time around.

No, for loops *do* rebind loop variables each time around. People are 
assuming that 'i' is immediately bound to its 'current' value, just like 
default args. (This is the opposite of people who mis-assume that 
default arg expressions are re-evaluated with each call.) This 
assumption is tied much more to 'lambda' than 'def'.

 > He may not *realise* he's assuming that, but he is.
> Given that people seem to unconsciously make that
> assumption,

*Some* people -- those who come from a language that does whatever it is 
that python does not do that you want it to do.

> perhaps we should consider making the
> for-loop actually behave that way. There's a precedent
> for this -- list comprehensions used to leak their
> loop variable into the surrounding scope, but that
> was eventually changed.

This has *nothing* to do with people assuming early binding of names in 
lambda expressions. The posted 'surprise code' typically uses list 
comps. So changing for loops to be like list comps would have no effect 
on that mis-assumptions and the resulting surprise.

Terry Jan Reedy

More information about the Python-ideas mailing list