2012-11-16 111 views
-2

我是新的python。你能解释这个代码吗?python函数定义

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

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

谢谢!

+2

你不理解的部分是什么? – Tadeck

+1

你如何投资一些时间阅读一本关于python的书? http://www.coderholic.com/free-python-programming-books/ – scape

回答

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 

这就是所谓的递归,你可以在网上找到优秀的解释。请记住,这是一个要遵循的过程,因此,当您看到阶乘(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行,永远不会到达兔子洞的底部。实际上,它可能会导致堆栈溢出错误,因为每个调用都会占用堆栈上的更多空间,并最终导致堆栈溢出。

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

+0

来自调用的调用堆栈的非常好的描述。 – sean

+0

@sean:干杯,你会改善什么? –