繁体   English   中英

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

[英]What is the explanation of the python code which uses anonymous lambda to implement factorial function

这个功能真的让我感到茫然。 任何人都可以解释关键的想法? 如果有一些示例来演示函数的工作方式会更好。

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

所以改写更长的形式:

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)

...但是这依赖于因子能够通过名称引用自己。 作为一个匿名函数,它不能这样做,所以它需要作为参数传递“本身”,因此它知道要调用谁。

func1func2只是设置系统来调用自身:

def func1(factorial_function):
  def func2(k):
    factorial(factorial_function, k))
func1(factorial)

这将返回一个函数( func2作为闭包,可以访问包含factorial_function的封闭范围)。 当调用func2时,它将调用factorial(factorial, k) ,从而计算阶乘函数。

我在这里写,因为我不能在评论中发布缩进代码。 @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未加密,我认为它完全没用。

我第二次@ TigerhawkT3的评论; 对代码进行编码也是最隐蔽的, 并不意味着这样的编码成为一个榜样,更不用说必须了。

糟糕的代码只是糟​​糕的代码,就是这样。

但无论如何 - 使用的方法是推动用于评估n! = n*(n-1)! lambda表达式n! = n*(n-1)! n! = n*(n-1)! 在调用堆栈上从N个向下的方式(参见下面的代码)到1,并且当1到达,堆栈被消耗从上到下,和lambda表达式表达进行评估,以在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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM