我想从Python中的常量列表创建lambda对象列表;例如:

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

但是,当我运行它们时,这将创建一个lambda对象列表:
for f in listOfLambdas:
    print f(),

我希望它会打印
1 4 9 16 25

而是打印:
25 25 25 25 25

似乎所有lambda都被赋予了错误的参数。我做错了什么,有办法解决吗?我认为我使用的是Python 2.4。

编辑:更多尝试的事情,例如这样:
listOfLambdas = []
for num in listOfNumbers:
    action = lambda: square(num)
    listOfLambdas.append(action)
    print action()

打印从1到25的期望平方,然后使用之前的print语句:
for f in listOfLambdas:
    print f(),

仍然给了我所有25。现有的lambda对象如何在这两个打印调用之间改变?

相关问题:Why results of map() and list comprehension are different?

最佳答案

我猜想您在列表理解中创建的lambda绑定(bind)到变量i,最终变量i最终为5。因此,当您对事实进行评估后,lambda都绑定(bind)为5并最终计算25.在第二个示例中,num也发生了同样的事情。当您评估循环内的lambda时,num的值没有改变,因此您获得了正确的值。循环后,num为5 ...

我不太确定您要做什么,所以不确定如何提出解决方案。这个怎么样?

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

这给了我预期的输出:
1
4
9
16
25

另一种思考方式是,lambda在创建时就“捕获”其词法环境。因此,如果给它 num ,它实际上不会解析该值,直到调用它。这既困惑又强大。

09-07 10:24