函數-遞歸調用、匿名

1、什麼是遞歸調用

遞歸調用:在函數調用過程當中,直接或間接地調用了函數自己,這就是函數的遞歸調用
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')

2、匿名函數 

當咱們在傳入函數時,有些時候,不須要顯式地定義函數,直接傳入匿名函數更方便。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

3、max、min、lambda  

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)
相關文章
相關標籤/搜索