Python中的Lambda递归和/或

2024-04-25 22:39:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我遇到了这个版本的阶乘练习,完全不知所措:

fac = lambda n: n and n * fac(n-1) or 1

这是我无法理解的和/或部分,尤其是和…部分。你知道吗

最后:当您在没有n and ...部分的情况下运行这个程序时,它会返回一个“超过最大递归深度”错误。你知道吗


Tags: orandlambda程序版本错误情况fac
3条回答

Lambda只是正则函数的另一种表示法。这样写很有帮助:

def fac(n):
    if n:
        return n * fac(n-1)
    else:
        return 1

在这种表示法中,更容易看到基本情况和递归情况。同样重要的是要知道布尔运算符orand总是返回它们的一个操作数:https://docs.python.org/3/library/stdtypes.html#truth-value-testing

在我看来,这段代码写得很糟糕,可能是一个认为自己很聪明的初学者写的(或者这可能是加快代码速度的一种方法,但在这种情况下,应该对它进行大量注释)。所以如果你不明白,那不是你的错,而是程序员的错

但我们来分析一下:

n and x or 1将返回:

  • 1如果n是0,因为无论x是什么,0 and x始终是0,并且由于快捷方式求值,x(即n*fax(n-1))从不求值;0 or 1是1。你知道吗
  • 如果n不是零,那么x就不能是0。你知道吗

所以n and x or 1处理递归的基本情况,当n达到0时停止它。这也是为什么删除“n和”时会出现“超过最大递归深度”错误的原因。你知道吗

剩下的只是阶乘的定义,我想我不需要在这里解释。你知道吗

以下是一个更理智和可读的版本:

fac = lambda n: (n * fac(n-1)) if n!=0 else 1

下面是我希望如何编写它,使其可读并以递归调用结束,因为某些编译器可能能够在这种情况下优化递归:

def fac(n):
    if n==0:
        return 1
    else:
        return n*fac(n-1)

当n为负时,这些函数都不能很好地处理未定义的情况(这会导致递归溢出),因此如果使用函数,就必须避免这种情况。你知道吗

这是一种写^{}/^{} expression的“聪明”方法。最好用这些关键字来表达:

fac = lambda n: n * fac(n-1) if n else 1

或者更明确地说:

fac = lambda n: (n * fac(n-1) if n != 0 else 1)

相关问题 更多 >

    热门问题