函式不僅可以巢狀定義,還可以巢狀呼叫,即在呼叫乙個函式的過程中,函式內部又呼叫另乙個函式,而函式的遞迴呼叫指的是在呼叫乙個函式的過程中又直接或間接地呼叫該函式本身
例如在呼叫f1的過程中,又呼叫f1,這就是直接呼叫函式f1本身
在呼叫f1的過程中,又呼叫f2,而在呼叫f2的過程中又呼叫f1,這就是間接呼叫函式f1本身
從上圖可以看出,兩種情況下的遞迴呼叫都是乙個無限迴圈的過程,但在python對函式的遞迴呼叫的深度做了限制,因而並不會像大家所想的那樣進入無限迴圈,會丟擲異常,要避免出現這種情況,就必須讓遞迴呼叫在滿足某個特定條件下終止。
#1. 可以使用sys.getrecursionlimit()去檢視遞迴深度,預設值為1000,雖然可以使用
sys.setrecursionlimit(
)去設定該值,但仍受限於主機作業系統棧大小的限制
#2. python不是一門函式式程式語言,無法對遞迴進行尾遞迴優化。
下面我們用乙個淺顯的例子,為了讓讀者闡釋遞迴的原理和使用:
例4.5
某公司四個員工坐在一起,問第四個人薪水,他說比第三個人多1000,問第三個人薪水,第他說比第二個人多1000,問第二個人薪水,他說比第乙個人多1000,最後第一人說自己每月5000,請問第四個人的薪水是多少?
思路解析:
要知道第四個人的月薪,就必須知道第三個人的,第三個人的又取決於第二個人的,第二個人的又取決於第乙個人的,而且每乙個員工都比前乙個多一千,數學表示式即:
salary(4)
=salary(3)
+1000
salary(3)
=salary(2)
+1000
salary(2)
=salary(1)
+1000
salary(1)
=5000
總結為:
很明顯這是乙個遞迴的過程,可以將該過程分為兩個階段:回溯和遞推。
在回溯階段,要求第n個員工的薪水,需要回溯得到(n-1)個員工的薪水,以此類推,直到得到第乙個員工的薪水,此時,salary(1)已知,因而不必再向前回溯了。然後進入遞推階段:從第乙個員工的薪水可以推算出第二個員工的薪水(6000),從第二個員工的薪水可以推算出第三個員工的薪水(7000),以此類推,一直推算出第第四個員工的薪水(8000)為止,遞迴結束。需要注意的一點是,遞迴一定要有乙個結束條件,這裡n=1就是結束條件。
**實現:
def
salary
(n):
if n==1:
return
5000
return salary(n-1)
+1000
s=salary(4)
print
(s)
執行結果:
程式分析:
在未滿足n==1的條件時,一直進行遞迴呼叫,即一直回溯,見圖4.3的左半部分。而在滿足n==1的條件時,終止遞迴呼叫,即結束回溯,從而進入遞推階段,依次推導直到得到最終的結果。
遞迴本質就是在做重複的事情,所以理論上遞迴可以解決的問題迴圈也都可以解決,只不過在某些情況下,使用遞迴會更容易實現,比如有乙個巢狀多層的列表,要求列印出所有的元素,**實現如下
items=[[
1,2]
,3,[
4,[5
,[6,
7]]]
]def
foo(items)
:for i in items:
ifisinstance
(i,list):
#滿足未遍歷完items以及if判斷成立的條件時,一直進行遞迴呼叫
foo(i)
else
:print
(i,end=
' ')
foo(items)
#列印結果1 2 3 4 5 6 7
使用遞迴,我們只需要分析出要重複執行的**邏輯,然後提取進入下一次遞迴呼叫的條件或者說遞迴結束的條件即可,**實現起來簡潔清晰
Day20 高階函式
今天主要學習了python中sorted,filter,map 三個高階函式,還了解了一下函式的柯里化 1.什麼是高階函式def way1 x return x 3 def way2 x return x x result way2 way1 7 print result 1002.標準庫中的高階函...
暑期訓練 day20
暑期訓練 day20 趙景樂今天看完了第二章的內容,有點多,現在想想記得的沒多少,還需要鞏固鞏固,找個時間再把相應的 打一打。今天訓練賽的a題錯了兩次,沒想到暴力能過,還是一開始打的麻煩了,c題是數學題,因為一開始沒優化到底,結果超時了,剪枝 改良公式也算剪枝吧,畢竟少了一重迴圈 後就過了,b題一開...
每日演算法 day 20
那些你早出晚歸付出的刻苦努力,你不想訓練,當你覺的太累了但還是要咬牙堅持的時候,那就是在追逐夢想,不要在意終點有什麼,要享受路途的過程,或許你不能成就夢想,但一定會有更偉大的事情隨之而來。mamba out 2020.3.3 卡特蘭數 include include include include ...