63 python recursion lambda y-combinator
常规函数可以在其定义中包含对自身的调用,没问题.我无法弄清楚如何使用lambda函数来做这件事,原因很简单,因为lambda函数没有可以引用的名称.有办法吗?怎么样?
Gre*_*ill 68
我能想到的唯一方法就是为函数命名:
fact = lambda x: 1 if x == 0 else x * fact(x-1)
Run Code Online (Sandbox Code Playgroud)
或者,对于早期版本的python:
fact = lambda x: x == 0 and 1 or x * fact(x-1)
Run Code Online (Sandbox Code Playgroud)
更新:使用其他答案中的想法,我能够将阶乘函数楔入一个未命名的lambda:
>>> map(lambda n: (lambda f, *a: f(f, *a))(lambda rec, n: 1 if n == 0 else n*rec(rec, n-1), n), range(10))
[1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
Run Code Online (Sandbox Code Playgroud)
所以这是可能的,但不是真的推荐!
Hug*_*ter 50
没有reduce,map,命名为lambdas或python内部:
(lambda a:lambda v:a(a,v))(lambda s,x:1 if x==0 else x*s(s,x-1))(10)
Run Code Online (Sandbox Code Playgroud)
Nux*_*Nux 24
与某些人说的相反,你可以直接这样做.
(lambda f: (lambda x: f(lambda v: x(x)(v)))(lambda x: f(lambda v: x(x)(v))))(lambda f: (lambda i: 1 if (i == 0) else i * f(i - 1)))(n)
Run Code Online (Sandbox Code Playgroud)
第一部分是定点组合子 Y,它有助于lambda演算中的递归
Y = (lambda f: (lambda x: f(lambda v: x(x)(v)))(lambda x: f(lambda v: x(x)(v))))
Run Code Online (Sandbox Code Playgroud)
第二部分是递归定义的阶乘函数事实
fact = (lambda f: (lambda i: 1 if (i == 0) else i * f(i - 1)))
Run Code Online (Sandbox Code Playgroud)
Y应用于事实以形成另一个lambda表达式
F = Y(fact)
Run Code Online (Sandbox Code Playgroud)
它应用于第三部分n,它被推广到第n个阶乘
>>> n = 5
>>> F(n)
120
Run Code Online (Sandbox Code Playgroud)
或者等价的
>>> (lambda f: (lambda x: f(lambda v: x(x)(v)))(lambda x: f(lambda v: x(x)(v))))(lambda f: (lambda i: 1 if (i == 0) else i * f(i - 1)))(5)
120
Run Code Online (Sandbox Code Playgroud)
然而,如果你喜欢小谎来的事实,你可以做到这一点使用相同的组合子
>>> (lambda f: (lambda x: f(lambda v: x(x)(v)))(lambda x: f(lambda v: x(x)(v))))(lambda f: (lambda i: f(i - 1) + f(i - 2) if i > 1 else 1))(5)
8
Run Code Online (Sandbox Code Playgroud)
sth*_*sth 23
你不能直接这样做,因为它没有名字.但是使用像Le-Lein指向的Y-combinator这样的辅助函数,你可以通过将函数作为参数传递给自身来创建递归(听起来很奇怪):
# helper function
def recursive(f, *p, **kw):
return f(f, *p, **kw)
def fib(n):
# The rec parameter will be the lambda function itself
return recursive((lambda rec, n: rec(rec, n-1) + rec(rec, n-2) if n>1 else 1), n)
# using map since we already started to do black functional programming magic
print map(fib, range(10))
Run Code Online (Sandbox Code Playgroud)
这将打印前十个Fibonacci数:[1, 1, 2, 3, 5, 8, 13, 21, 34, 55],
hab*_*bit 11
是.我有两种方法可以做到,其中一种已经被覆盖了.这是我的首选方式.
(lambda v: (lambda n: n * __import__('types').FunctionType(
__import__('inspect').stack()[0][0].f_code,
dict(__import__=__import__, dict=dict)
)(n - 1) if n > 1 else 1)(v))(5)
Run Code Online (Sandbox Code Playgroud)
这个答案非常基本。它比 Hugo Walter 的回答简单一点:
>>> (lambda f: f(f))(lambda f, i=0: (i < 10)and f(f, i + 1)or i)
10
>>>
Run Code Online (Sandbox Code Playgroud)
雨果沃尔特的回答:
(lambda a:lambda v:a(a,v))(lambda s,x:1 if x==0 else x*s(s,x-1))(10)
Run Code Online (Sandbox Code Playgroud)
我们现在可以使用新的 python 语法来使其更短且更易于阅读:
斐波那契:
>>> (f:=lambda x: 1 if x <= 1 else f(x - 1) + f(x - 2))(5)
8
Run Code Online (Sandbox Code Playgroud)
阶乘:
>>> (f:=lambda x: 1 if x == 0 else x*f(x - 1))(5)
120
Run Code Online (Sandbox Code Playgroud)
我们用来:=命名 lambda:直接在 lambda 本身中使用名称并立即将其作为匿名函数调用。
(参见https://www.python.org/dev/peps/pep-0572)
| 归档时间: |
|
| 查看次数: |
34741 次 |
| 最近记录: |