How do I create a list of Python lambdas in a list comprehensionfor loop

De openkb
Aller à : Navigation, rechercher

Sommaire

Questions

I want to create a list of lambda objects from a list of constants in Python; for instance:

listOfNumbers = [1,2,3,4,5]
square = lambda x: x * x
listOfLambdas = [lambda: square(i) for i in listOfNumbers]

This will create a list of lambda objects, however, when I run them:

for f in listOfLambdas:
    print f(),

I would expect that it would print

1 4 9 16 25

Instead, it prints:

25 25 25 25 25

It seems as though the lambdas have all been given the wrong parameter. Have I done something wrong, and is there a way to fix it? I m in Python 2.4 I think.

EDIT: a bit more of trying things and such came up with this:

listOfLambdas = []
for num in listOfNumbers:
    action = lambda: square(num)
    listOfLambdas.append(action)
    print action()

Prints the expected squares from 1 to 25, but then using the earlier print statement:

for f in listOfLambdas:
    print f(),

still gives me all 25s. How did the existing lambda objects change between those two print calls?

http://stackoverflow.com/questions/139819/why-results-of-map-and-list-comprehension-are-different http://stackoverflow.com/questions/139819/why-results-of-map-and-list-comprehension-are-different

Answers

I m guessing that the lambda you re creating in the list comprehension is bound to the variable i which eventually ends up at 5. Thus, when you evaluate the lambdas after the fact, they re all bound to 5 and end up calculating 25. The same thing is happening with num in your second example. When you evaluate the lambda inside the loop it s num hasn t changed so you get the right value. After the loop, num is 5...

I m not quite sure what you re going for, so I m not sure how to suggest a solution. How about this?

def square(x): return lambda : x*x
listOfLambdas = [square(i) for i in [1,2,3,4,5]]
for f in listOfLambdas: print f()

This gives me the expected output:

1
4
9
16
25

Another way to think of this is that a lambda "captures" its lexical environment at the point where it is created. So, if you give it num it doesn t actually resolve that value until its invoked. This is both confusing and powerful.

Source

License : cc by-sa 3.0

http://stackoverflow.com/questions/452610/how-do-i-create-a-list-of-python-lambdas-in-a-list-comprehension-for-loop

Related

Outils personnels
Espaces de noms

Variantes
Actions
Navigation
Outils