可能重复: function making
>>> g=lambda x:x+1
>>> composition=lambda f,g:(lambda x:f(g(x)))
>>> f=g
>>> f=composition(f,g)
>>> f(9)
11
>>> f=composition(f,g)
>>> f=composition(f,g)
>>> f=composition(f,g)
>>> f(9)
14我没有使用函数组合(f,g),而是执行了以下操作
>>> f=g
>>> f=lambda x:f(g(x))
>>> f(8)
RuntimeError: maximum recursion depth exceeded我只是想用相应的lambda表达式代替函数组合。我不明白为什么f=composition(f,g)不是产生递归,而是f=lambda x:f(g(x))产生递归。
发布于 2012-09-14 21:25:15
关于第一项:
调用composition(f, g)时,您将围绕这些变量的内容创建一个闭包。要返回的lambda正在查找其本地作用域中的变量名f和g --它们都是对在第一行中创建的g lambda的引用。
关于第二个问题:
在第二种情况下,当调用f时,它在其“本地”作用域(实际上是全局作用域)中查找f,并发现它自己,从而创建无限递归。
这里的关键是f的查找是在执行时进行的,而不是在定义lambda时进行的。
发布于 2012-09-14 21:27:02
当你写这个时:
f=lambda x:f(g(x))由此产生的lambda的意思是“在调用x上的范围中的任何g的结果上调用范围内的任何f”。
当你写这个时:
f=composition(f, g)由此产生的函数意味着“调用组合的第一个参数基于调用组合的第二个参数的结果”。
我不知道你需要更好地理解哪些细节才能弄清楚这一点,但我来猜猜看。在Python中传递的参数总是通过引用,而不是名称。所以,当您调用复合( f,g)时,您传递的是f所引用的函数对象,而不是“变量”f。但是当您定义lambda时,这只发生在作用域中,因此您是在引用f本身。
另外,这也是Guido不喜欢使用lambda语法的原因之一。如果您像这样重写代码,那么所发生的事情就更明显了:
def g(x): return x+1
def composition(f,g):
def composed(x): return f(g(x))
return composed
f=g
f=composition(f,g)https://stackoverflow.com/questions/12432097
复制相似问题