这个功能让我感到很沮丧。任何人都可以解释关键的想法?如果有一些示例来演示函数的工作原理会更好。
from operator import sub, mul
def make_anonymous_factorial():
"""Return the value of an expression that computes factorial.
>>> make_anonymous_factorial()(5)
120
"""
return (lambda f: lambda k: f(f, k))(lambda f, k: k if k == 1 else mul(k, f(f, sub(k, 1))))
答案 0 :(得分:3)
所以改写更长的形式:
def make_anonymous_factorial():
def func1(f):
def func2(k):
return f(f, k))
return func2
def func3(f, k):
if k == 1:
return k
else:
return mul(k, f(f, sub(k, 1)))
return func1(func3)
再次简化:
def make_anonymous_factorial():
def func1(factorial_function):
def func2(k):
factorial_function(factorial_function, k))
return func2
def factorial(recursive_func, k):
if k == 1:
return k
else:
return k * recursive_func(recursive_func, k-1)
return func1(factorial)
通常情况下你可以写像:
def factorial(k):
if k == 1:
return k
else:
return k * factorial(k-1)
...但是这依赖于factorial能够通过名称引用自己。作为一个匿名函数,它不能这样做,所以它需要通过"本身"作为一个论点,它知道应该给谁打电话。
func1
和func2
只是设置系统自行调用:
def func1(factorial_function):
def func2(k):
factorial(factorial_function, k))
func1(factorial)
这将返回一个函数(func2
作为闭包,可以访问包含factorial_function
的封闭范围。调用时func2
将调用factorial(factorial, k)
,从而计算阶乘函数。
答案 1 :(得分:1)
我在这里写,因为我不能在评论中发布缩进代码。 @MikeLambert:代码的第一部分是错误的。它应该是:
def func1(f):
def func2(k):
return f(f, k)
return func2
对Dimen61的解释:这是因为lambda
函数是定义函数的“捷径”。所以:
lambda x, y, z...: some_expression
相当于
def someFunction(x, y, z):
return some_expression
回到我们的“嵌套”lambdas
lambda f: lambda k: f(f, k)
表达式可以翻译成
def func1(f):
return lambda k: f(f, k)
并转换另一个lambda,你获得上面的表达式。
我还要补充一点,我完全同意TigerhawkT3:这段代码很难看,即使Lambert未加密,我认为它完全没用。
答案 2 :(得分:0)
我是第二张@ TigerhawkT3的评论;那些编码也是最隐蔽的,不暗示这样的编码是一个榜样,更不用说必须了。
糟糕的代码只是糟糕的代码而且就是这样。
但是无论如何 - 使用的方法是将用于评估调用堆栈上的n! = n*(n-1)!
的lambda表达式从N(参见下面的代码)向下推进到1,当达到1
时,堆栈从上到下消耗,lambdas表达式计算为它们产生的int
。
一些小仪器显示了这一点:
from operator import sub, mul
N = 5
def up_(k, f):
print(' '*(N - k + 1), k, f)
return mul(k, f)
def down_(f, k):
print(' '*(N - k), k, 'f')
return k if k == 1 else up_(k, f(f, sub(k, 1)))
def make_anonymous_factorial():
"""Return the value of an expression that computes factorial.
>>> make_anonymous_factorial()(5)
120
"""
return (lambda f: lambda k: f(f, k))(
lambda f, k: down_(f, k)
)
print(make_anonymous_factorial()(N))
输出:
5 f
4 f
3 f
2 f
1 f
2 1
3 2
4 6
5 24
120