递归 - Python,返回值问题

Posted

技术标签:

【中文标题】递归 - Python,返回值问题【英文标题】:Recursion - Python, return value question 【发布时间】:2010-12-08 18:36:09 【问题描述】:

我意识到这听起来像是一个愚蠢的问题,但我上次编写它是在汇编程序中,所以我的想法可能是错误的:

这样的递归函数:

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

为什么当函数到达 n == 0 时它不返回 1 而是返回阶乘的答案。我在想像在汇编程序中那样的东西,当 n == 0 时:

mov eax, 1
ret

为什么上面的代码可以工作,我想python返回那个条件之前堆栈上的最后一个值?

【问题讨论】:

【参考方案1】:

这样想,例如fac(5)

return 5 * fac(4)
           return 4 * fac(3)
                      return 3 * fac(2)
                                 return 2 * fac(1)
                                            return 1 * fac(0)
                                                       1

所以1 将是第一个 返回值,但它会返回到fac(1)fac(1) 将返回到fac(2) 等等。

【讨论】:

+1:记住,“函数”的返回值并不是整个表达式的返回值,它涉及到许多乘法和函数调用。这完全是关于“调用堆栈”和评估函数的上下文。 谢谢,这是一个基本的错过。但我认为这是我的错误,这完全有道理,干杯!【参考方案2】:

确实在 n == 0 时返回 1。该返回值从调用站点的堆栈中弹出,这是在 n * fac(n - 1) 处的调用。 1 乘以 n 并返回,等等。

【讨论】:

是的,但是可以说 n == 4,它仍然会迭代并递减一个计数器,直到它到达行尾,在我的逻辑中是当 n == 0 时,即不再剩下的数字要相乘。也许我在这里混淆了一些非常基本的东西,但我没有找到任何关于 Python 如何进行递归的解释。我也可以使用 do while 循环来执行此功能,然后会更清楚。但正如它现在所写的那样,我只是无法遵循逻辑,希望这是有道理的?【参考方案3】:

如果您调用 fac(0) 它将返回 1(不是 0,但我想这只是您问题中的一个错字)。如果你调用 fac(1),它将进入 else 子句,并在那里调用fac(0)。这将返回 1。然后它将计算 n*1,即 1,并将其返回。如果你调用fac(2),它也将进入else 子句,在那里它将调用fac(1),如上所述将返回1,所以n*fac(n-1) 将是2,这就是fac(2) 的返回值。等等。我希望能为你解释它。

【讨论】:

【参考方案4】:

没有隐式返回 - 当 n=0 时,函数进入 if 语句,并直接从 return 1 语句返回 1。 但是,这不是将“阶乘答案”返回给用户的点。相反,它可能会将此值返回给 调用 由 fac(1) 调用的函数,它位于 n * fac(n - 1) 分支的中间。因此它将返回“1”并返回n*1,它是1 给它的 调用者。如果是 fac(2),它将返回 n * 1,或 2 给 它的调用者等等。

因此 fac(5) 被翻译为:

fac(5) = 5 * fac(4) = 5 * (4 * fac(3) = 5 * (4* (3 * fac(2)) = 5 * (4* (3 * (2 * fac(1)) = 5 * (4* (3 * (2 * (1 * fac(0)) = 5*4*3*2*1*1

只有在通过每个上层返回 1 值后,它才会返回到第一个调用者,每个阶段的乘法会给你答案。

【讨论】:

【参考方案5】:

James,当对您的函数的最终调用(当 n==0 时)返回时,它只是调用堆栈上的几个 fac(n) 实例之一。如果说 print(fac(4)),栈本质上是:

fac(0)
fac(1)
fac(2)
fac(3)
fac(4)
print()

对 fac(0) 的最终调用适当地返回 1,但是在 Python 中,您已经请求了对 fac(n) 的第一次调用的返回值,即 fac(4)。

不要认为它是一个循环,其中 'ret' 会爆发,返回只是结束几个待执行的执行之一。

【讨论】:

以上是关于递归 - Python,返回值问题的主要内容,如果未能解决你的问题,请参考以下文章

python第三篇 python基础之函数,递归,内置函数

Python递归

python基础:递归函数返回值(return)误区

python 复习 4-1 函数参数返回值递归

14 python初学(高阶函数 递归函数 内置函数)

返回值递归问题