列表推导中的Lambda [英] Lambdas inside list comprehensions
问题描述
我想要一个lambda列表,它们充当某种繁重计算的缓存,并注意到了这一点:
I wanted to have a list of lambdas that act as sort of a cache to some heavy computation and noticed this:
>>> [j() for j in [lambda:i for i in range(10)]]
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
尽管
>>> list([lambda:i for i in range(10)])
[<function <lambda> at 0xb6f9d1ec>, <function <lambda> at 0xb6f9d22c>, <function <lambda> at 0xb6f9d26c>, <function <lambda> at 0xb6f9d2ac>, <function <lambda> at 0xb6f9d2ec>, <function <lambda> at 0xb6f9d32c>, <function <lambda> at 0xb6f9d36c>, <function <lambda> at 0xb6f9d3ac>, <function <lambda> at 0xb6f9d3ec>, <function <lambda> at 0xb6f9d42c>]
意思是lambda是唯一的函数,但是它们都以某种方式共享相同的索引值.
Meaning that the lambdas are unique functions but they somehow all share the same index value.
这是错误还是功能?我如何避免这个问题?不仅限于列表理解...
Is this a bug or a feature? How do I avoid this problem? It's not limited to list comprehensions...
>>> funcs = []
... for i in range(10):
... funcs.append(lambda:i)
... [j() for j in funcs]
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
推荐答案
lambda
会在调用时返回i
的值.由于在循环运行完成后调用lambda
,因此i
的值将始终为9.
The lambda
returns the value of i
at the time you call it. Since you call the lambda
after the loop has finished running, the value of i
will always be 9.
您可以在lambda中创建一个局部i
变量,以保存定义lambda
时的值:
You can create a local i
variable in the lambda to hold the value at the time the lambda
was defined:
>>> [j() for j in [lambda i=i:i for i in range(10)]]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
另一种解决方案是创建一个返回lambda
的函数:
Another solution is to create a function that returns the lambda
:
def create_lambda(i):
return lambda:i
>>> [j() for j in [create_lambda(i) for i in range(10)]]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
之所以起作用,是因为为每个create_lambda
调用创建了一个不同的闭包(持有不同的i
值).
This works because there is a different closure (holding a different value of i
) created for each invocation of create_lambda
.
这篇关于列表推导中的Lambda的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!