首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >功能制作

功能制作
EN

Stack Overflow用户
提问于 2012-09-14 21:16:44
回答 2查看 118关注 0票数 2

可能重复: function making

代码语言:javascript
复制
>>> 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),而是执行了以下操作

代码语言:javascript
复制
>>> 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))产生递归。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-09-14 21:25:15

关于第一项:

调用composition(f, g)时,您将围绕这些变量的内容创建一个闭包。要返回的lambda正在查找其本地作用域中的变量名fg --它们都是对在第一行中创建的g lambda的引用。

关于第二个问题:

在第二种情况下,当调用f时,它在其“本地”作用域(实际上是全局作用域)中查找f,并发现它自己,从而创建无限递归。

这里的关键是f的查找是在执行时进行的,而不是在定义lambda时进行的。

票数 2
EN

Stack Overflow用户

发布于 2012-09-14 21:27:02

当你写这个时:

代码语言:javascript
复制
f=lambda x:f(g(x))

由此产生的lambda的意思是“在调用x上的范围中的任何g的结果上调用范围内的任何f”。

当你写这个时:

代码语言:javascript
复制
f=composition(f, g)

由此产生的函数意味着“调用组合的第一个参数基于调用组合的第二个参数的结果”。

我不知道你需要更好地理解哪些细节才能弄清楚这一点,但我来猜猜看。在Python中传递的参数总是通过引用,而不是名称。所以,当您调用复合( f,g)时,您传递的是f所引用的函数对象,而不是“变量”f。但是当您定义lambda时,这只发生在作用域中,因此您是在引用f本身。

另外,这也是Guido不喜欢使用lambda语法的原因之一。如果您像这样重写代码,那么所发生的事情就更明显了:

代码语言:javascript
复制
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)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12432097

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档