簡體   English   中英

了解遞歸函數調用

[英]Understanding recursive functions calls

考慮以下代碼:

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

print_mah(3)

在這里,Python檢查n是否小於或等於0,它發現這是False,因此它打印'mah'並用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,它發現這是False,因此再次用n-1調用同一函數,並且'mah'也被打印3次。

我的問題是,為什么不一次打印'mah',換句話說,為什么不使用n = 2調用print_mah,然后Python發現條件為False ,所以用n = 1進行調用,並找到條件為False ,因此它以n == 0進行調用,並發現條件為True ,因此該函數返回,並且在打印'mah'之后僅返回一次。

要了解不同之處,這可能會有所幫助。

算法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)中調用一個函數(f2),則當前函數(f1)將等待,直到被調用函數(f2)完成。

一些研究關鍵詞

  • 函數調用

Python發現條件為False,因此以n = 1對其進行調用,並發現條件為False,因此以n == 0對其進行調用,並發現該條件為True,因此該函數返回

這實際上是第二個版本的確切執行路徑。 但是,也許您看不到,當函數返回時,它會像遞歸調用一樣返回在遞歸調用返回從中斷處恢復的位置。

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

這兩個函數將打印mah 3次,因為在遞歸調用之后您沒有返回任何內容。 當您在內部調用函數時,應該處理停止條件(您在第一個if條件中已經執行過),然后在此之后它不會退出程序,因為遞歸調用會生成一系列操作。 在最后一個操作停止后(返回某項),然后它將在返回的遞歸調用下方開始編譯該函數的其余部分,直到到達該函數的末尾。

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

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

print_mah(3)

在返回0之前, print_mah被調用了3次。您可以認為它們只是嵌套的邏輯,如下所示:

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')

您會看到print('mah')依次顯示在底部,正如所寫的那樣,當函數從調用堆棧中回退時,它將順序打印。

這是第二個程序正在做的“跟蹤”:

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')出現了3次(因此,'mah'被打印了3次)。

我的問題是為什么不一次打印'mah',換句話說為什么不使用n = 2調用print_mah,然后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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM