首页>Program>source

以下测试失败:

#!/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-11
    1 #

    它们是不同的,因为 i的值 生成器表达式和list comp中的值都是惰性计算的,即在 f中调用匿名函数时 .
    那时, i 如果 t绑定到最后一个值 ,即-1。

    所以基本上,这就是列表理解的功能(对于genexp也是如此):

    x = []
    i = 1 # 1. from t
    x.append(lambda: i)
    i = -1 # 2. from t
    x.append(lambda: i)
    

    现在,lambda携带一个引用 i的闭合 ,但 i 在这两种情况下都绑定为-1,因为这是它被分配给的最后一个值。

    如果要确保lambda收到 i的当前值 ,做

    f(*[lambda u=i: u for i in t])
    

    这样,您就可以对 i进行评估 在创建封包时。

    Edit :生成器表达式与列表理解之间有一个区别:后者将循环变量泄漏到周围的范围中。

  • 2021-1-11
    2 #

    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-11
    3 #

    表达式 f = lambda: i 等效于:

    def f():
        return i
    

    表达 g = lambda i=i: i 等效于:

    def g(i=i):
        return i
    

    i 在第一种情况下为自由变量,在第二种情况下为函数参数绑定,即在这种情况下为局部变量.默认参数的值在函数定义时进行评估.

    Generator表达式是最接近的范围(其中 ii定义) 在 lambda中的名字 表达,因此 i 在该块中得到解决:

    f(*(lambda: i for i in (1, -1)) # -> [-1, -1]
    

    ilambda i: ...的局部变量 块,因此它引用的对象在该块中定义:

    f(*map(lambda i: lambda: i, (1,-1))) # -> [1, -1]
    

相关问题

  • excel:运行时错误'1004':对象'_Global'的方法'Range'失败
  • java:如何在Swing中为JTable提供分页支持?