一个常规功能可以包含在其定义中,没有问题本身的呼叫。我无法弄清楚如何使用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)

<强>更新:使用从思想其他的答案,我能够楔阶乘函数成一个单一的λ无名:

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

所以这是可能的,但并不推荐使用!

其他提示

,而不减少,地图,命名的lambda或Python内部:

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

您不能直接这样做,因为它没有名字。但随着像Y型组合子米指着一个辅助功能,你可以通过函数作为参数传递给自身创造递归(如奇怪,这听起来):

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

在第一部分是定点组合子 ý便于在递归演算

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

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

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

ý被施加到事实以形成另一lambda表达式

F = Y(fact)

被施加到所述第三部分,名词的,这evaulates至第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,但大概是你所期待的。

此答案是非常基本的。它比雨果Walter的回答更简单一点:

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

雨果Walter的答案:

(lambda a:lambda v:a(a,v))(lambda s,x:1 if x==0 else x*s(s,x-1))(10)
def recursive(def_fun):
    def wrapper(*p, **kw):
        fi = lambda *p, **kw: def_fun(fi, *p, **kw)
        return def_fun(fi, *p, **kw)

    return wrapper


factorial = recursive(lambda f, n: 1 if n < 2 else n * f(n - 1))
print(factorial(10))

fibonaci = recursive(lambda f, n: f(n - 1) + f(n - 2) if n > 1 else 1)
print(fibonaci(10))

希望这将是有益的人。

好了,不完全是纯朗母递归,但它在的地方,在那里你可以只使用lambda表达式,例如是适用减少,地图和列表内涵,或其他lambda表达式。诀窍是从列表理解和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

在拉姆达重用在列表解析表达式(FN)定义它的名字。的例子中是相当复杂的,但它显示的概念。

有关这一点,我们可以使用固定点组合的,具体Z组合子,因为它会严格语言工作,也叫渴望的语言:

const Z = f => (x => f(v => x(x)(v)))(x => f(v => x(x)(v)))

定义fact功能,并修改它:

1. const fact n = n === 0 ? 1 : n * fact(n - 1)
2. const fact = n => n === 0 ? 1 : n * fact(n - 1)
3. const _fact = (fact => n => n === 0 ? 1 : n * fact(n - 1))

注意:

  

事实=== Z(_fact)

和使用它:

const Z = f => (x => f(v => x(x)(v)))(x => f(v => x(x)(v)));

const _fact = f => n => n === 0 ? 1 : n * f(n - 1);
const fact = Z(_fact);

console.log(fact(5)); //120

参见: 定点在JavaScript组合子:Memoizing递归函数

LAMBDA可以很容易地替换在Python递归函数:

例如,这个基本compound_interest:

def interest(amount, rate, period):
    if period == 0: 
        return amount
    else:
        return interest(amount * rate, rate, period - 1)

可以被代替:

lambda_interest = lambda a,r,p: a if p == 0 else lambda_interest(a * r, r, p - 1)

或更多的可见性:

lambda_interest = lambda amount, rate, period: \
amount if period == 0 else \
lambda_interest(amount * rate, rate, period - 1)

用法:

print(interest(10000, 1.1, 3))
print(lambda_interest(10000, 1.1, 3))

输出:

13310.0
13310.0

如果你是真正的受虐狂,你也许能够使用C扩展做到这一点,但呼应格雷格(喜格雷格!),这超过了拉姆达的能力(无名,匿名)functon。

没有。 (对于没有最值)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top