[Tutor] lambda in a loop

Christian Wyglendowski Christian.Wyglendowski at greenville.edu
Wed Nov 16 22:39:44 CET 2005


> -----Original Message-----
> From: tutor-bounces at python.org 
> [mailto:tutor-bounces at python.org] On Behalf Of Fred Lionetti
> Sent: Wednesday, November 16, 2005 2:32 PM
> To: tutor at python.org
> Subject: [Tutor] lambda in a loop
> 
> Hi everyone,

Hello,
 
>  If I have this code:
> 
> --------------------------------
>  def doLambda(val):
>    print "value 2:", val
> 
>  commands = []
>  for value in range(5):
>    print "value 1:", value
>    commands.append(lambda:doLambda(value))
> 
>  for c in commands:
>    c()
> ----------------------------------
> 
>  my output is:
>  value 1: 0
>  value 1: 1
>  value 1: 2
>  value 1: 3
>  value 1: 4
>  value 2: 4
>  value 2: 4
>  value 2: 4
>  value 2: 4
>  value 2: 4
> 
>  Obviously, the lambda is using "value" at the end of the loop (4),
> rather than what I want, "value" during the loop (0,1,2,3).  

Right.  I think the issue is that your lambda calls another funtion.
However, the function isn't called until the lambda is called later,
when value == 4.

> Is there
> any *simple* way around this?  I'd prefer not to use a separate array
> with all the values ( i.e.
> commands.append(lambda:doLambda(values[commands.index(c)])) ) if
> possible.

I'd use a closure rather than a lambda. 

def wrapper(val):
    def inner():
        print "value 2:", val
    return inner

commands = []
for value in range(5):
    print "value 1:", value
    commands.append(wrapper(value))

for c in commands:
    c()

That way each item in commands is an "inner" function that has its own
local copy of value.  So it is really a variable scope issue.


>  Thanks,
>  Fred

HTH, sorry it isn't more clear.

Christian


More information about the Tutor mailing list