2012-11-16 115 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:乾杯,你會改善什麼? –