为什么下面两个列表推导式的输出不同,即使f和lambda函数是相同的?

f = lambda x: x*x
[f(x) for x in range(10)]

and

[lambda x: x*x for x in range(10)]

注意,type(f)和type(lambda x: x*x)返回相同的类型。


当前回答

第一个函数创建一个lambda函数并调用它十次。

第二个不调用函数。它创建了10个不同的函数。它把所有这些都放在一个列表中。为了使它与第一个等价,你需要:

[(lambda x: x*x)(x) for x in range(10)]

或者更好的是:

[x*x for x in range(10)]

其他回答

人们给出了很好的答案,但忘记了我认为最重要的部分: 在第二个例子中,列表推导式的X与lambda函数的X并不相同,它们完全不相关。 所以第二个例子实际上是一样的

[Lambda X: X*X for I in range(10)]

range(10)上的内部迭代只负责在列表中创建10个相似的lambda函数(10个独立的但完全相似的函数-返回每个输入的幂2)。

另一方面,第一个例子的工作方式完全不同,因为迭代中的X确实与结果相互作用,对于每个迭代的值都是X*X,因此结果将是[0,1,4,9,16,25,36,49,64,81]

第一个函数创建一个lambda函数并调用它十次。

第二个不调用函数。它创建了10个不同的函数。它把所有这些都放在一个列表中。为了使它与第一个等价,你需要:

[(lambda x: x*x)(x) for x in range(10)]

或者更好的是:

[x*x for x in range(10)]

其他答案是正确的,但如果你试图创建一个函数列表,每个函数都有不同的参数,可以稍后执行,下面的代码将完成这一任务:

import functools
a = [functools.partial(lambda x: x*x, x) for x in range(10)]

b = []
for i in a:
    b.append(i())

In [26]: b
Out[26]: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

虽然这个例子是虚构的,但当我想要一个函数列表,每个函数都打印不同的东西时,我发现它很有用。

import functools
a = [functools.partial(lambda x: print(x), x) for x in range(10)]

for i in a:
    i()

最大的区别是,第一个例子实际上调用了f(x),而第二个例子没有。

第一个例子等价于[(lambda x: x*x)(x) for x in range(10)],而第二个例子等价于[f for x in range(10)]。

第一个

f = lambda x: x*x
[f(x) for x in range(10)]

对范围内的每个值运行f(),因此对每个值执行f(x)

第二个

[lambda x: x*x for x in range(10)]

为列表中的每个值运行lambda,因此它生成所有这些函数。