Lambda表达式和字典

3

你好,

我对以下内容感到困惑:

v = {}

v[-1] = lambda x: 1
v[0]  = lambda x: x

for k in range(1, n):    # k = 1...n-1   
    v[k] = lambda x: 2*x*v[k-1](x) - v[k-2](x)

当我调用v[3](1)时,会生成一个错误maximum recursion depth exceeded,而这个:

v = {}  

v[-1] = lambda x: 1
v[0]  = lambda x: x

v[1] = lambda x: 2*x*v[1-1](x) - v[1-2](x)
v[2] = lambda x: 2*x*v[2-1](x) - v[2-2](x)
v[3] = lambda x: 2*x*v[3-1](x) - v[3-2](x)

这个程序运行得很好。我无法弄清楚Python在第一种情况下的投诉是什么。建议会很有帮助。

2个回答

4
正如Inbar Rose所指出的那样,k是全局变量,在lambda创建时不会被评估。然而,有一种方法可以让Python在声明时评估k:
for k in range(1, n):    # k = 1...n-1   
    v[k] = lambda x, k=k: 2*x*v[k-1](x) - v[k-2](x)

这个k=k声明了一个局部变量k,它是lambda函数内可选的,默认值是在声明时k的值。


3
在Python中,Lambda是闭包。你给Lambda的参数在Lambda被评估之前不会被评估。那时,无论如何,k=n,因为你的迭代已经完成。
证明:
>>> l = {}
>>> for k in range(1, 10):
    l[k] = lambda x: k
>>> for v in l.values():
    print v('')


9
9
9
9
9
9
9
9
9

2
此外,使用dis模块,dis.dis(v[1])会得到这样一行有趣的代码:10 LOAD_GLOBAL 1 (k),它表明在循环期间,k的值没有被计算。 - njzk2
那确实是个问题...但你还没有提出解决方案。 - martineau
问题是“是什么导致了这种行为”,而这个回答了这个问题。我无法提供确切的解决方案,因为现在OP意识到他的计划行不通,他应该想出一个新的想法,如果他有问题,可以再问另一个问题,此外,@njzk2提供了一个可以为OP工作的解决方案(虽然可能不完全是OP想要的)。 - Inbar Rose

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接