在python中生成函数列表

时间:2010-12-13 05:07:19

标签: python list lambda

我有以下python代码生成匿名函数列表:

basis = [ (lambda x: n*x) for n in [0, 1, 2] ]     
print basis[0](1)

我原以为它等同于

basis = [ (lambda x: 0*x), (lambda x: 1*x), (lambda x: 2*x) ]
print basis[0](1)

然而,虽然第二个片段打印出0,这是我所期望的,但第一个打印出来2.第一段代码有什么问题,为什么它没有按预期运行?

4 个答案:

答案 0 :(得分:8)

您可以使用默认参数在n

上创建闭包
>>> basis = [ (lambda x,n=n: n*x) for n in [0, 1, 2] ]     
>>> print basis[0](1)
0

答案 1 :(得分:3)

因为它"通过名称"。

也就是说,当lambda运行时,它会执行n*xx绑定到1(它是一个参数),n是在环境中查找(现在2 )。所以,结果是2。

答案 2 :(得分:2)

问题在于,在第一个示例中,每个lambda绑定到相同的n - 换句话说,它捕获变量,而不是变量的值。由于n在循环结束时的值为2,因此每个lambda对n使用值2。

显然,您可以使用默认参数来解决此问题:

basis = [ (lambda x,n=n: n*x) for n in [0, 1, 2] ]
print basis[0](1) 

由于默认参数值是常量,因此每次循环时都会评估n右侧的n=n,以便为您提供新的捕获值。

答案 3 :(得分:0)

我想帮助理解Karl Knechtel的评论(12月13日和10日在7:32)。下面的代码显示了如何使用生成器,原始的lambda定义给出了预期的结果,但它没有使用list或tuple:

>>> #GENERATOR
... basis = ( (lambda x: n*x) for n in [0, 1, 2] )  
>>> print(type(basis))
<type 'generator'>
>>> basis = ( (lambda x: n*x) for n in [0, 1, 2] ) 
>>> print([x(3) for x in basis])
[0, 3, 6]
>>> #TUPLE
... basis = tuple( (lambda x: n*x) for n in [0, 1, 2] )
>>> print(type(basis))
<type 'tuple'>
>>> print([x(3) for x in basis])
[6, 6, 6]
>>> #LIST
... basis = list( (lambda x: n*x) for n in [0, 1, 2] )
>>> print(type(basis))
<type 'list'>
>>> print([x(3) for x in basis])
[6, 6, 6]
>>> #CORRECTED LIST
... basis = list( (lambda x, n=n: n*x) for n in [0, 1, 2] )
>>> print(type(basis))
<type 'list'>
>>> print([x(3) for x in basis])
[0, 3, 6]