-3

我是python新手。你能解释一下这段代码吗?

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

>>>print factorial(5)
>>>120

谢谢!

4

1 回答 1

4
def factorial(n):            # define a function, receiving a value 'n'
    if n == 0:               # if n is 0, then...
        return 1             #    return the result 1 to the calling code (done!)
    return n*factorial(n-1)  # otherwise return n times the result of calling
                             #  this function (factorial) with the lower value

>>>print factorial(5)

# factorial(5): 5 != 0, so return 5 * factorial(4)
#   factorial(4): 4 != 0 ...
#     ...
#           factorial(0) = 1 returns to factorial(1) call:
#         factorial(1) = 1 * 1 = 1, returns to factorial(2) call:
#       factorial(2) = 2 * 1 = 2
#     factorial(3) = 3 * 2 = 6
#   factorial(4) = 4 * 6 = 24
# factorial(5) = 5 * 24 = 120, return this

>>>120

这叫做递归,你可以在网上找到很好的解释。请记住,这是一个要遵循的过程,因此当您看到 factorial(n-1) 表达式时,python 正在计算 n-1,然后factorial使用此值开始对此处的新调用。结果是每次调用都会再次调用,factorial直到最终达到 0,并且它可以开始返回堆栈到最外面的调用。想象一下自己尝试解决这个问题,你会发现你正在做同样的事情:

(5 * (4 * (3 * (2 * (1 * 1)))))

在您知道其中括号的值等之前,您无法完成最外面的括号。

但请注意,代码有一个重大缺陷:如果 n-1-1-1-1-1 等永远不会达到 0(例如,如果 n=1.1),那么它永远不会到达该return 1行,也永远不会到达兔子洞的底部。事实上,它可能会导致堆栈溢出错误,因为每次调用都会占用堆栈上的更多空间,最终会耗尽。

为了进一步研究,了解尾调用递归(这是一个示例)以及当递归调用位于返回语句(尾)中时编译器如何解决堆栈溢出问题。

于 2012-11-16T15:17:04.350 回答