6

Consider this example

def dump(value):
    print value

items = []    
for i in range(0, 2):
    items.append(lambda: dump(i))

for item in items:
    item()

output:

1
1

how can i get:

0
1
eumiro
  • 207,213
  • 34
  • 299
  • 261
Bojan Radojevic
  • 1,015
  • 3
  • 16
  • 26

4 Answers4

5

You can use a parameter with a default value on the lambda:

for i in range(0, 2):
    items.append(lambda i=i: dump(i))

This works because the default value is evaluated when the function is defined, not when it is called.

Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
  • man, you are smart. This was example but you found workaround, the point was how to eval that reference on lambda definition. Is there a way for doing that? – Bojan Radojevic Oct 11 '12 at 14:22
4

You can use:

for i in range(0, 2):
    items.append(lambda i=i: dump(i))

to capture the current value of i

This works because default parameter values are evaluated at function creation time, and i is not the external variable, but a function parameter that will have the value you want as default.

A more detailed explanation can be found in this answer.

Community
  • 1
  • 1
Paolo Moretti
  • 54,162
  • 23
  • 101
  • 92
1

For completeness, you can also do:

for i in range(0, 2):
    items.append((lambda i: lambda: dump(i))(i))
newacct
  • 119,665
  • 29
  • 163
  • 224
  • I feel this answer is the least hacky, even though it's more verbose than the default value answer. – max Oct 12 '12 at 02:25
0

The output value is the value of i at the evaluation of the function, not at its declaration. That's why you don't get the desired result.

Nicolas Barbey
  • 6,639
  • 4
  • 28
  • 34