python代码的解释是什么,它使用匿名lambda来实现阶乘函数

时间:2015-12-10 09:42:17

标签: python recursion lambda

这个功能让我感到很沮丧。任何人都可以解释关键的想法?如果有一些示例来演示函数的工作原理会更好。

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

3 个答案:

答案 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能够通过名称引用自己。作为一个匿名函数,它不能这样做,所以它需要通过"本身"作为一个论点,它知道应该给谁打电话。

func1func2只是设置系统自行调用:

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