递归lambda表达式可能吗?

Eri*_*fka 18 python recursion lambda

我正在尝试编写一个调用自身的lambda表达式,但我似乎无法找到任何语法,即使它是可能的.

基本上我想将以下函数转移到以下lambda表达式中:(我意识到它是一个愚蠢的应用程序,它只是添加,但我正在探索我可以用python中的lambda表达式做什么)

def add(a, b):
   if a <= 0:
      return b
   else:
      return 1 + add(a - 1, b)

add = lambda a, b: [1 + add(a-1, b), b][a <= 0]
Run Code Online (Sandbox Code Playgroud)

但调用lambda形式的add会导致运行时错误,因为达到了最大递归深度.甚至可以在python中执行此操作?或者我只是犯了一些愚蠢的错误?哦,我正在使用python3.0,但我认为这不重要吗?

Ben*_*ngs 19

也许你需要一个Y组合器?

编辑 - 使其成为一个Z组合子(我没有意识到Y组合器更适合于按名称调用)

使用来自维基百科的Z组合子的定义

>>> Z = lambda f: (lambda x: f(lambda *args: x(x)(*args)))(lambda x: f(lambda *args: x(x)(*args)))
Run Code Online (Sandbox Code Playgroud)

使用它,您可以将add定义为完全匿名的函数(即在其定义中没有引用其名称)

>>> add = Z(lambda f: lambda a, b: b if a <= 0 else 1 + f(a - 1, b))
>>> add(1, 1)
2
>>> add(1, 5)
6
Run Code Online (Sandbox Code Playgroud)

  • 或磁通电容器 (11认同)
  • 懒惰将是**def add(a,b):返回a + b**:P (3认同)

Bar*_*lly 8

也许你应该尝试Z组合器,这个例子来自:

>>> Z = lambda f: (lambda x: f(lambda *args: x(x)(*args)))(lambda x: f(lambda *args: x(x)(*args)))
>>> fact = lambda f: lambda x: 1 if x == 0 else x * f(x-1)
>>> Z(fact)(5)
120
Run Code Online (Sandbox Code Playgroud)

  • 我只是在嘴里吐了一点. (5认同)
  • 它的味道像lambda吗? (3认同)
  • 您需要使用Haskell而不是Python,或者需要使用lambda表达式退出.你很危险 :P (3认同)

Len*_*bro 6

首先,递归lambda表达式是完全没必要的.正如您自己所指出的,对于lambda表达式来调用自身,它需要有一个名称.但lambda表达式只不过是匿名函数.因此,如果给lambda表达式一个名称,它不再是lambda表达式,而是一个函数.

因此,使用lambda表达式是没用的,只会让人迷惑.所以用def来创建它.

但是,就像你自己发现的那样,lambda表达式可以是递归的.你自己的例子是.事实上它是如此奇妙的递归,你超过了最大递归深度.所以这是递归好的.你的问题是你总是在表达式中调用add,所以递归永远不会停止.不要那样做.你的表达式可以这样表达:

add = lambda a, b: a > 0 and (1 + add(a-1, b)) or b
Run Code Online (Sandbox Code Playgroud)

这解决了这个问题.但是,你的第一个def是正确的方法.

  • 拥有或不拥有名称与某事物是否为lambda完全无关.lambda是一个逻辑*表达式*(它恰好具有与函数相同的接口).给他们一个名字是完全平凡的. (10认同)
  • 我对理论数学没兴趣.你说lambda是一个匿名函数,给lambda一个名字使它不是lambda.你错了.匿名或有名字与Python lambda是否为lambda完全无关. (4认同)
  • "如果你给lambda表达式一个名字,它就不再是一个lambda表达式".它就在那里,这是错的.我已经完成了讨论. (4认同)