我想从Python中的常量列表创建一个lambda对象列表;例如:
listOfNumbers = [1,2,3,4,5]
square = lambda x: x * x
listOfLambdas = [lambda: square(i) for i in listOfNumbers]
但是,当我运行lambda对象时,这将创建一个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的预期正方形,然后使用前面的打印语句:
for f in listOfLambdas:
print f(),
仍然给我所有的25
。在这两个打印调用之间,现有的lambda对象是如何更改的
相关问题:Why results of map() and list comprehension are different?
我猜您在列表理解中创建的lambda绑定到变量I,该变量最终为5。因此,当您在事后评估lambda时,它们都被绑定为5,最终计算为25。在第二个示例中,num也发生了同样的情况。当您在循环中计算lambda时,它的num没有改变,因此您可以得到正确的值。循环之后,num是5
我不太确定你的目的是什么,所以我不确定如何提出解决方案。这个怎么样
这给了我预期的输出:
另一种方式是lambda在创建时“捕获”其词汇环境。因此,如果您给它num,它实际上不会解析该值,直到调用它。这既令人困惑,又很强大
当函数语句被执行时,它们被绑定到它们的(词汇上的)封闭范围
在您的代码段中,lambda被绑定到全局作用域,因为
for
套件在Python中不是作为独立作用域单元执行的。在for
循环的末尾,num
被绑定在封闭范围内。演示:因此,当您在
for
循环中绑定标识符时,实际上是在操作封闭范围列表理解的相同处理:
令人兴奋,我知道。根据我们新发现的知识,我们可以确定您正在创建的lambda引用的是封闭范围中绑定的(单个)
num
标识符。这应该让这更有意义:这是最酷的部分,更能说明这一点:
当然,解决这个问题的方法是为每个要绑定的
number
创建一个新的封闭范围。在Python中,可以使用模块、类和函数创建新的封闭作用域。通常使用一个函数只是为另一个函数创建新的封闭范围在Python中,闭包是一个返回另一个函数的函数。有点像函数构造函数。查看以下示例中的
get_fun
:因为
get_fun
是一个函数,所以它有自己的内部作用域。每次使用值调用get_fun
,都会创建一个小表来跟踪其中的绑定;i、 它说,“在这个范围内,value
标识符指向传递的东西。”这个范围在函数执行结束时消失,除非有理由让它挂起如果您从作用域内返回函数,这就是“作用域表”的一部分挂起的一个很好的原因——您要返回的函数可以在稍后调用它时引用该作用域表中的内容。因此,当在
get_fun
中创建fun
时,Python会告诉fun
关于get_fun
的作用域表,该表在需要时随时可用你可以在Python docs on the execution model中阅读更多关于细节和技术术语(我稍微软化了一点)的信息。您还可以查看函数使用
print fun.__closure__
引用的封闭作用域部分。在上面,我们看到对value
的引用,它恰好是一个int:你有:
输出:
你需要咖喱!除了美味之外,使用这个默认值“hack”
输出:
请注意
i=i
。这就是魔法发生的地方相关问题 更多 >
编程相关推荐