Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
119 views
in Technique[技术] by (71.8m points)

How do I create a list of Python lambdas (in a list comprehension/for loop)?

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?

Related question: Why results of map() and list comprehension are different?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You have:

listOfLambdas = [lambda: i*i for i in range(6)]

for f in listOfLambdas:
    print f()

Output:

25
25
25
25
25
25

You need currying! Aside from being delicious, use this default value "hack".

listOfLambdas = [lambda i=i: i*i for i in range(6)]

for f in listOfLambdas:
    print f()

Output:

0
1
4
9
16
25

Note the i=i. That's where the magic happens.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...