一个lambda函数可以在Python中recursion调用吗?

一个普通的函数可以在其定义中包含对自身的调用,没有问题。 我不知道如何使用lambda函数来做到这一点,虽然简单的理由是,lambda函数没有名称可以返回。 有没有办法做到这一点? 怎么样?

我能想到的唯一办法就是给这个函数一个名字:

fact = lambda x: 1 if x == 0 else x * fact(x-1) 

或者,对于早期版本的python:

 fact = lambda x: x == 0 and 1 or x * fact(x-1) 

更新 :使用从其他答案的想法,我能够将阶乘函数楔入一个单一的无名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] 

所以这是可能的,但不是真的推荐!

没有减less,地图,名为lambdas或python的内部:

 (lambda a:lambda v:a(a,v))(lambda s,x:1 if x==0 else x*s(s,x-1))(10) 

你不能直接做,因为它没有名字。 但是,像Lemmy所指出的Y辅助函数一样,你可以通过将函数作为parameter passing给自己来创buildrecursion:

 # 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)) 

这打印了前十个斐波那契数字: [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

与此相反,你可以直接做到这一点。

 (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) 

第一部分是有助于lambda演算recursion的定点组合器 Y.

 Y = (lambda f: (lambda x: f(lambda v: x(x)(v)))(lambda x: f(lambda v: x(x)(v)))) 

第二部分是recursion定义的阶乘函数事实

 fact = (lambda f: (lambda i: 1 if (i == 0) else i * f(i - 1))) 

Y被应用于事实形成另一个lambdaexpression式

 F = Y(fact) 

这是应用到第三部分, n ,它蒸发到第n阶乘

 >>> n = 5 >>> F(n) 120 

或等同地

 >>> (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 

但是,如果你喜欢纤维 事实,你也可以使用相同的组合器

 >>> (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 

是。 我有两种方法可以做到,一个已经被覆盖了。 这是我喜欢的方式。

 (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) 

我从来没有使用Python,但这可能是你在找什么。

这个答案是非常基本的。 这比Hugo Walter的答案简单一点:

 >>> (lambda f: f(f))(lambda f, i=0: (i < 10)and f(f, i + 1)or i) 10 >>> 

雨果·沃尔特的回答:

 (lambda a:lambda v:a(a,v))(lambda s,x:1 if x==0 else x*s(s,x-1))(10) 

那么,不完全是纯粹的lambdarecursion,但是它适用于只能使用lambdaexpression式的地方,例如reduce,map和list comprehensions或其他lambdaexpression式。 诀窍是受益于列表理解和Python的名称范围。 以下示例通过给定的键链遍历字典。

 >>> data = {'John': {'age': 33}, 'Kate': {'age': 32}} >>> [fn(data, ['John', 'age']) for fn in [lambda d, keys: None if d is None or type(d) is not dict or len(keys) < 1 or keys[0] not in d else (d[keys[0]] if len(keys) == 1 else fn(d[keys[0]], keys[1:]))]][0] 33 

lambda重用在列表理解expression式(fn)中定义的名称。 这个例子相当复杂,但它显示了这个概念。

如果你确实是受虐狂的,那么你也许可以用C扩展来做到这一点,但是为了回应Greg(嗨,Greg!),这超出了lambda(无名,匿名)function的能力。

没有(对于大多数的否)。