我想从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 ,它实际上不会解析该值,直到调用它。这既困惑又强大。