[英]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.