Python之遞迴函式
阿新 • • 發佈:2022-05-03
Python之遞迴函式 好久沒有更新內容了,也好久沒有給大家打個招呼了,小白想死你們了。今天跟大家說說Python中的遞迴函式。
Python是支援遞迴函式的。簡單地說,一個遞迴函式就是直接或間接地呼叫自身的函式,並且要有退出條件。枯燥的概念令人生厭,我們直接來個例子看看遞迴函式是如何工作的。
例如我們對一個數字列表進行求和計算,我們可以使用內建的sum
函式或者自己寫一個函式來完成計算工作,接下來我們看看如何使用遞迴來完成求和運算:
In[1]: def mysum(L): ...: if not L: ...: return 0 ...: else: ...: return L[0] + mysum(L[1:]) ...: In[2]: mysum([1, 2, 3, 4, 5]) Out[2]: 15
如果對上面的函式較為困惑,可以使用print
函式來列印每次遞迴時列表L
的值:
In[3]: def mysum(L):
...: print(L)
...: if not L:
...: return 0
...: else:
...: return L[0] + mysum(L[1:])
...:
In[4]: mysum([1, 2, 3, 4, 5])
[1, 2, 3, 4, 5]
[2, 3, 4, 5]
[3, 4, 5]
[4, 5]
[5]
[]
Out[4]: 15
通過上述的輸出可以發現:每次遞迴時,列表的長度都變短了,直到列表變為空時,遞迴終止。
對於上面的程式碼,我們可以使用另外一種程式碼形式來實現,也就是使用三目運算子,然而在Python中是沒有三目運算子的,不過可以使用if/else
來實現,程式碼如下:
In[1]: def mysum(L):
...: return 0 if not L else L[0] + mysum(L[1:])
...:
In[2]: mysum([1, 2, 3, 4, 5])
Out[2]: 15
說到遞迴還有一個階乘的例子要個大家說說:
In[5]: def factorial(number): ...: if number <=1: ...: return 1 ...: else: ...: return number * factorial(number-1) ...: In[6]: for i in range(11): ...: print("{0:2}! = {1}".format(i, factorial(i))) ...: 0! = 1 1! = 1 2! = 2 3! = 6 4! = 24 5! = 120 6! = 720 7! = 5040 8! = 40320 9! = 362880 10! = 3628800
如果計算factorial(5)
,可以根據函式定義看到其計算過程:
===> factorial(5)
===> 5 * factorial(4)
===> 5 * (4 * factorial(3))
===> 5 * (4 * (3 * factorial(2)))
===> 5 * (4 * (3 * (2 * factorial(1))))
===> 5 * (4 * (3 * (2 * 1)))
===> 5 * (4 * (3 * 2))
===> 5 * (4 * 6)
===> 5 * 24
===> 120
使用遞迴函式需要注意防止棧溢位。在計算機中,函式呼叫是通過棧(stack) 這種資料結構實現的,每當進入一個函式呼叫,棧就會加一層棧幀,每當函 數返回,棧就會減一層棧幀。由於棧的大小不是無限的,所以,遞迴呼叫的 次數過多,會導致棧溢位。可以試試factorial(1000):
>>> factorial(1000)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in factorial
...
File "<stdin>", line 4, in factorial
RuntimeError: maximum recursion depth exceeded
使用遞迴函式的優點是邏輯簡單清晰,缺點是過深的呼叫會導致棧溢位。
今天的內容就到這裡,明天繼續。