为什么map()和列表解析的结果不同? [英] Why results of map() and list comprehension are different?

查看:131
本文介绍了为什么map()和列表解析的结果不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下测试失败:

 #!/ usr / bin / env python 
def f ):

>>> 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] $ b
alist = [a()for a in args]
print(alist)

如果__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]


解决方案

它们是不同的,因为生成器表达式和列表comp中的 i 的值是懒惰的,即当匿名函数在 f 中调用。

到那时, i t ,这是-1。



所以基本上,这是列表推导所做的):

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


b $ b

现在lambdas继承一个引用 i 的闭包,但 i 绑定到-1



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

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

这样,您强制执行 i :生成器表达式和列表推导有一个区别:后者泄漏循环变量进入周围范围。


The following test fails:

#!/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()

In other words:

>>> 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]

解决方案

They are different, because the value of i in both the generator expression and the list comp are evaluated lazily, i.e. when the anonymous functions are invoked in f.
By that time, i is bound to the last value if t, which is -1.

So basically, this is what the list comprehension does (likewise for the genexp):

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

Now the lambdas carry around a closure that references i, but i is bound to -1 in both cases, because that is the last value it was assigned to.

If you want to make sure that the lambda receives the current value of i, do

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

This way, you force the evaluation of i at the time the closure is created.

Edit: There is one difference between generator expressions and list comprehensions: the latter leak the loop variable into the surrounding scope.

这篇关于为什么map()和列表解析的结果不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆