2016-03-24 54 views
0

考慮下面的代碼:理解遞歸函數調用

def print_mah(n): 
    if n <= 0: 
     return 
    else: 
     print('mah') 
     print_mah(n-1) 

print_mah(3) 

這裏的Python檢查是否n是小於或等於0時,它發現,這是所以它打印「麻將」並調用相同函數與n-1直到n等於0,所以'mah'被打印3次。

但是考慮這個操作的代碼:

def print_mah(n): 
    if n <= 0: 
     return 
    else: 
     print_mah(n-1) 
     print('mah') 

print_mah(3) 

Python的檢查,如果n小於或等於0時,它發現,這是所以用n-1再次調用相同的功能,和' mah'也打印3次。

我的問題是,爲什麼「麻將」不打印只是一個時間,換句話說,爲什麼print_mah不叫其中n = 2,那麼Python認定條件爲,所以它與調用它n = 1,發現條件是False,所以它用n == 0調用它,發現條件是,所以函數返回,之後'mah'被打印出來,只有一次。

+1

兩個版本都有打印語句。一路打印下來。一路上打印它。你誤讀了這個條件 - 它檢查遞歸是否完成。所有其他案件涉及印刷品。 –

回答

1

Python的認定條件爲假,所以它有n = 1調用它,並找到條件是False,所以用n == 0調用它,並且發現條件爲True,所以函數返回

這實際上是第二個版本的確切執行路徑。但是,也許你沒有看到,當函數返回時,它將在之後的處繼續遞歸調用返回,就像其他任何方法調用一樣。

因此,當n==1並將其與n==0遞歸,然後它被返回和mah被印刷在第一次,則該返回和mahn==2,然後返回被打印並且mah打印在第三和最後的時間。

+0

哦!你是對的,我不知道我怎麼忘記了。非常感謝你! –

1

要了解不同,也許這可以幫助。

算法1

def print_n(n): 
    if n <= 0: 
     return 
    else: 
     print_n(n-1) 
     print(n) 

算法2

def print_n(n): 
    if n <= 0: 
     return 
    else: 
     print(n) 
     print_n(n-1) 

這些算法應該提供不同的結果,也許這是進一步研究的很好的起點。

一些幫助

如果您在呼叫其他職能(F1)當前函數(F1)內的函數(F2)將等到被調用的函數(F2)完成。

一些關鍵字的研究

  • 函數調用
+0

在第一種情況下,它應該按升序打印從1到n的數字。但第二個算法應該按照降序排列。 – Querenker

+0

你是對的,對不起!我犯了一個錯誤,輸入print(3)而不是print_n(3) –

1

這兩個函數都會打印mah三次,因爲你不是在遞歸調用後返回什麼。當你在自己內部調用函數時,你應該處理停止條件(你已經在你的第一個if條件中做了這個),然後它不會退出程序,因爲遞歸調用會構建一堆操作。在最後一個操作停止後(返回一些東西),它將開始在遞歸調用之後編譯函數的其餘部分,直到函數結束。

1

return不會突破你的整個調用堆棧,只是當前的函數調用。在這種情況下:

def print_mah(n): 
    if n <= 0: 
     return 
    else: 
     print_mah(n-1) 
     print('mah') 

print_mah(3) 

print_mah將返回0。前三次調用,您可以考慮一下,如果他們只是嵌套的邏輯是這樣的:

def print_mah(n): 
    if n <= 0: 
     return 
    else: 
     print_mah(n-1) # Replace this line with new call 
     print('mah') 

如果我們只是再次調用該函數在評論的else語句中。

def print_mah(n): 
    if n <= 0: 
     #return 
    else: 
     n = n-1 
     if n <= 0: 
      #return 
     else: 
      print_mah(n-1) 
      print('mah') 
     print('mah') 

你可以看到打印(「麻將」)顯示了在底部,其中,因爲它是寫,將依次爲功能原路返回函數調用棧的打印序列。

1

這裏是一個什麼樣的第二個程序是做「痕跡」:

print_mah(3) -> 
    print_mah(2) -> 
    print_mah(1) -> 
     print_mah(0) -> 
     # Does nothing, essentially. 
     <- 
     # print_mah(1) continues running. 
     print('mah') # The last thing that print_mah(1) does. 
     <- 
    # print_mah(2) continues running. 
    print('mah') 
    <- 
    # print_mah(3) continues running. 
    print('mah') 
    <- 

我們在這裏看到的是,print('mah')發生三次(因此,「麻將」被印刷三次)。

1

我的問題是爲什麼'mah'不是隻打印一次,換句話說爲什麼print_mah不是用n = 2調用,那麼Python發現條件是False,所以它調用它n = 1,並且發現條件是False,所以它用n == 0調用它,並且發現條件是True,所以函數返回,並且在'mah'被打印之後,僅打印一次。

該函數只返回最內層函數。在調用print_mah並實際打印之後,將使用else條件的兩個功能級別繼續執行。爲簡潔起見,此處爲print_mah(2)逐行瀏覽。

print_mah(2) 
# Enter print_mah - Level 1 

    if n <= 0: # n = 2 
     # ... 
    # False, continue to else 

    else: 
     print_mah(n-1) # n = 2 
    # Enter print_mah - Level 2 

     if n <= 0: # n = 1 
     # ... 
     # False, continue to else 

     else: 
      print_mah(n-1) # n = 1 
     # Enter print_mah - Level 3 

      if n <= 0: # n = 0 
       return 
      # Return None to print_mah - Level 2 

     print('mah') 
     # Function is complete, return None to print_mah - Level 1 

    print('mah') 
    # Function is complete, return None to the execution scope