lambda trouble

Terry Reedy tjreedy at udel.edu
Fri Mar 19 13:07:29 EST 2004


"Darabos Daniel" <cyhawk at sch.bme.hu> wrote in message
news:Pine.GSO.4.58L0.0403191736410.14978 at balu...
> Hi!
>
> I was doing something like this:
>
> >>> def p( x ):
> ...     print x
> ...
> >>> l = []
> >>> for i in range( 5 ):
> ...     l.append( lambda: p( i ) )
> ...
> >>> for k in l:
> ...     k()
> ...
> 4
> 4
> 4
> 4
> 4
>
> And it surprised me a little. I was expecting to see 0, 1, 2, 3, 4.

If you had written

for i in range(5):
  def f(): return p(i)
  l.append(f)

would you have still been surprised?  Or given that f is constant, how
about the exactly equivalent

def f(): return p(i)
for i in range(5):
  l.append(f)

or even the equivalent

def f(): return p(j)
for i in range(5):
  l.append(f)
j=i
def p(z): print z
<etc>


> After some brainwork I now kind of understand what happens and I even
> found a solution like this:
>
> >>> def mylambda( fn, *args ):
> ...     return lambda: apply( fn, args )
> ...
> >>> l = []
> >>> for i in range( 5 ):
> ...     l.append( mylambda( p, i ) )
> ...
> >>> for k in l:
> ...     k()
> ...
> 0
> 1
> 2
> 3
> 4
>
> But I still feel a bit unsatisfied. Do you have some advice for me?

Remember that 1) 'lambda args: expr' basically abbreviates 'def f(args):
return expr'; and 2)  function code bodies only execute when the function
is called, and in particular, do not dereference or access globals until
called.  While a function is being constructed, it is irrelevant that a
global even exist, let along that it be in use as a loop var.

Terry J. Reedy







More information about the Python-list mailing list