以下测试失败:
#!/usr/bin/env python
def f(*args):
"""
>>> t = 1, -1
>>> f(*map(lambda i: lambda: i, t))
[1, -1]
>>> f(*(lambda: i for i in t)) # -> [-1, -1]
[1, -1]
>>> f(*[lambda: i for i in t]) # -> [-1, -1]
[1, -1]
"""
alist = [a() for a in args]
print(alist)
if __name__ == '__main__':
import doctest; doctest.testmod()
换句话说:
>>> t = 1, -1
>>> args = []
>>> for i in t:
... args.append(lambda: i)
...
>>> map(lambda a: a(), args)
[-1, -1]
>>> args = []
>>> for i in t:
... args.append((lambda i: lambda: i)(i))
...
>>> map(lambda a: a(), args)
[1, -1]
>>> args = []
>>> for i in t:
... args.append(lambda i=i: i)
...
>>> map(lambda a: a(), args)
[1, -1]
最新回答
- 2021-1-111 #
- 2021-1-112 #
lambda捕获变量,而不是值,因此捕获代码
lambda : i
将始终返回值i为 currently 必然要在关闭.到调用它时,此值已设置为-1。
要获得所需的内容,您需要通过以下方式捕获创建lambda时的实际绑定:
>>> f(*(lambda i=i: i for i in t)) # -> [-1, -1] [1, -1] >>> f(*[lambda i=i: i for i in t]) # -> [-1, -1] [1, -1]
- 2021-1-113 #
表达式
f = lambda: i
等效于:def f(): return i
表达
g = lambda i=i: i
等效于:def g(i=i): return i
i
在第一种情况下为自由变量,在第二种情况下为函数参数绑定,即在这种情况下为局部变量.默认参数的值在函数定义时进行评估.Generator表达式是最接近的范围(其中
i
为i
定义) 在lambda
中的名字 表达,因此i
在该块中得到解决:f(*(lambda: i for i in (1, -1)) # -> [-1, -1]
i
是lambda i: ...
的局部变量 块,因此它引用的对象在该块中定义:f(*map(lambda i: lambda: i, (1,-1))) # -> [1, -1]
它们是不同的,因为
i
的值 生成器表达式和list comp中的值都是惰性计算的,即在f
中调用匿名函数时 .那时,
i
如果t
绑定到最后一个值 ,即-1。所以基本上,这就是列表理解的功能(对于genexp也是如此):
现在,lambda携带一个引用
i
的闭合 ,但i
在这两种情况下都绑定为-1,因为这是它被分配给的最后一个值。如果要确保lambda收到
i
的当前值 ,做这样,您就可以对
i
进行评估 在创建封包时。Edit :生成器表达式与列表理解之间有一个区别:后者将循环变量泄漏到周围的范围中。