遞歸調用:在函數調用過程當中,直接或間接地調用了函數自己,這就是函數的遞歸調用
1.遞歸的優勢
遞歸函數的優勢是定義簡單,邏輯清晰。理論上,全部的遞歸函數均可以寫成循環的方式,但循環的邏輯不如遞歸清晰。python
使用遞歸函數須要注意防止棧溢出。在計算機中,函數調用是經過棧(stack)這種數據結構實現的,每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。因爲棧的大小不是無限的,因此,遞歸調用的次數過多,會致使棧溢出。能夠試試fact(1000)
:數據結構
2.遞歸的缺點
解決遞歸調用棧溢出的方法是經過尾遞歸優化,事實上尾遞歸和循環的效果是同樣的,因此,把循環當作是一種特殊的尾遞歸函數也是能夠的。函數
尾遞歸是指,在函數返回的時候,調用自身自己,而且,return語句不能包含表達式。這樣,編譯器或者解釋器就能夠把尾遞歸作優化,使遞歸自己不管調用多少次,都只佔用一個棧幀,不會出現棧溢出的狀況。優化
3.遞歸案例ui
#階乘計算 def fact(n): if n==1: return 1 return n * fact(n - 1)
分析 ===> fact(5) ===> 5 * fact(4) ===> 5 * (4 * fact(3)) ===> 5 * (4 * (3 * fact(2))) ===> 5 * (4 * (3 * (2 * fact(1)))) ===> 5 * (4 * (3 * (2 * 1))) ===> 5 * (4 * (3 * 2)) ===> 5 * (4 * 6) ===> 5 * 24 ===> 120
4.二分法spa
#二分法 l = [1, 2, 10,33,53,71,73,75,77,85,101,201,202,999,11111] def search(find_num,seq): if len(seq) == 0: print('not exists') return mid_index=len(seq)//2 mid_num=seq[mid_index] print(seq,mid_num) if find_num > mid_num: #in the right seq=seq[mid_index+1:] search(find_num,seq) elif find_num < mid_num: #in the left seq=seq[:mid_index] search(find_num,seq) else: print('find it')
當咱們在傳入函數時,有些時候,不須要顯式地定義函數,直接傳入匿名函數更方便。code
在Python中,對匿名函數提供了有限支持。仍是以map()
函數爲例,計算f(x)=x2時,除了定義一個f(x)
的函數外,還能夠直接傳入匿名函數:對象
經過對比能夠看出,匿名函數lambda x: x * x
實際上就是:blog
def f(x): return x * x
關鍵字lambda
表示匿名函數,冒號前面的x
表示函數參數。遞歸
匿名函數有個限制,就是隻能有一個表達式,不用寫return
,返回值就是該表達式的結果。
用匿名函數有個好處,由於函數沒有名字,沒必要擔憂函數名衝突。此外,匿名函數也是一個函數對象,也能夠把匿名函數賦值給一個變量,再利用變量來調用該函數:
f = lambda x: x * x f(5) 結果25
一樣,也能夠把匿名函數做爲返回值返回,好比:
def build(x, y): return lambda: x * x + y * y
1.max、min、lambda
salaries={ 'egon':3000, 'alex':100000000, 'wupeiqi':10000, 'yuanhao':2000 } print(max(salaries.values())) res=zip(salaries.vaues(),salaries.key()) print(max(res)) 結果(100000,alex)
salaries={ 'egon':3000, 'alex':100000000, 'wupeiqi':10000, 'yuanhao':2000 }
print(max(salaries,key=lambda k:salaries[k]))#salarier每次迭代將字典的k值賦值給k print(min(salaries,key=lambda k:salaries[k]))#salarier每次迭代將字典的k值賦值給k
print(sorted(salaries,key=lambda x:salaries[x])) 每次迭代將字典的k值賦值給x,默認是最小到大
print(sorted(salaries,key=lambda x:salaries[x],reverse=True)) #加reverse參數 True從大到小
2.global
#應用 x=1000 def f1(): global x#若是使用關鍵字global那麼此時使用函數內定義的x x=0 f1() print(x) 結果 x=0
3.map應用
l=["1",'2','3'] res=map(lambda x:x+'sb',l)#迭代l列表並將每一個元素加一個sb print(list(res)) 結果: ['1sb', '2sb', '3sb'] 求每一個值得平方 nums=(1,2,3,4) res=map(lambda x:x**2,nums) print(linst(res))
4.reduce
l=[1,2,3,4] print(reduce(lambda x,y:x+y,l))#先拿到一個初始值而後而後和後邊的值累加 #帶初始值的 print(reduce(lambda x,y:x+y,l,10))若是初始值是10的話那麼每次結果跟10相加
5.filter
l=[1,2,3,4] fes=filter(lambda x:x>2,l) print(list(fes)) l=("hanhan_s","li_s") fes=filter(lambda x:x.endswith("s"),l)