1. 程式人生 > >python全棧開發之匿名函式和遞迴函式

python全棧開發之匿名函式和遞迴函式

python全棧開發,匿名函式,遞迴函式

匿名函式

lambda函式也叫匿名函式,即函式沒有具體的名稱。是為了解決一些功能很簡單需求而設計的一句話函式。如下:

#這段程式碼defcalc(n):returnn**nprint(calc(10))#換成匿名函式calc =lambdan:n**nprint(calc(10))

lambda語法

上面是我們對calc這個匿名函式的分析,下面給出了一個關於匿名函式格式的說明

函式名 = lambda 引數 :返回值

#引數可以有多個,用逗號隔開

#匿名函式不管邏輯多複雜,只能寫一行,且邏輯執行結束後的內容就是返回值

#返回值和正常的函式一樣可以是任意資料型別

我們可以看出,匿名函式並不是真的不能有名字。

匿名函式的呼叫和正常的呼叫也沒有什麼分別。 就是 函式名(引數) 就可以了,那匿名函式有什麼好處呢?

1 使用Python寫一些執行指令碼時,使用lambda可以省去定義函式的過程,讓程式碼更加精簡。

2 對於一些抽象的,不會別的地方再複用的函式,有時候給函式起個名字也是個難題,使用lambda不需要考慮命名的問題。

3 使用lambda在某些時候讓程式碼更容易理解。

lambda函式主要和其他函式結合使用,比如下面的例子:

#有這樣一個字典,怎樣取得一個字典中對於的值最大的鍵,我們都知道max(dict)預設得到的是鍵的最大值(按ascii)dic={'k1':10,'k2':100,'k3':30}print(max(dic))print(dic[max(dic,key=lambdak:dic[k])])Output:k3100

一下是max的原始碼:

defmax(*args, key=None):# known special case of max"""

    max(iterable, *[, default=obj, key=func]) -> value

    max(arg1, arg2, *args, *[, key=func]) -> value

 

    With a single iterable argument, return its biggest item. The

    default keyword-only argument specifies an object to return if

    the provided iterable is empty.

    With two or more arguments, return the largest argument.

    """pass

第二個例子:

res=map(lambdax:x**2,[1,5,7,4,8])fori in res:print(i)Output:125491664

Map 函式解析:

Python中的map函式應用於每一個可迭代的項,返回的是一個結果list。如果有其他的可迭代引數傳進來,map函式則會把每一個引數都以相應的處理函式進行迭代處理。map()函式接收兩個引數,一個是函式,一個是序列,map將傳入的函式依次作用到序列的每個元素,並把結果作為新的list返回。

第三個例子

res=filter(lambdax:x>10,[5,8,11,9,15])fori in res:print(i)Output:1115

Filter函式解析:

filter()函式接收一個函式 f 和一個list,這個函式 f 的作用是對每個元素進行判斷,返回 True或 False,filter()根據判斷結果自動過濾掉不符合條件的元素,返回由符合條件元素組成的新list。

總結:

匿名函式一般配合map,max,min,filter,zip函式使用

遞迴函式

遞迴函式的定義:在一個函式裡面在呼叫自己本身。注意: 遞迴的最大深度——997

遞迴函式如果不受到外力的阻止會一直執行下去。但是我們之前已經說過關於函式呼叫的問題,每一次函式呼叫都會產生一個屬於它自己的名稱空間,如果一直呼叫下去,就會造成名稱空間佔用太多記憶體的問題,於是python為了杜絕此類現象,強制的將遞迴層數控制在了997(只要997!你買不了吃虧,買不了上當...).拿什麼來證明這個“997理論”呢?這裡我們可以做一個實驗:

deffoo(n):print(n)    n +=1foo(n)foo(1)Output:1...993994995996Traceback (most recent call last):  File"D:/Study/BaiduNetdiskDownload/day15課堂筆記/Func.py", line139,in    foo(1)  File"D:/Study/BaiduNetdiskDownload/day15課堂筆記/Func.py", line138,infoo    foo(n)  File"D:/Study/BaiduNetdiskDownload/day15課堂筆記/Func.py", line138,infoo    foo(n)  File"D:/Study/BaiduNetdiskDownload/day15課堂筆記/Func.py", line138,infoo    foo(n)  [Previous line repeated992more times]  File"D:/Study/BaiduNetdiskDownload/day15課堂筆記/Func.py", line136,infoo    print(n)RecursionError: maximum recursion depth exceededwhilecalling a Python object

由此我們可以看出,未報錯之前能看到的最大數字就是997.當然了,997是python為了我們程式的記憶體優化所設定的一個預設值,我們當然還可以通過一些手段去修改它:

import sysprint(sys.setrecursionlimit(100000))

我們可以通過這種方式來修改遞迴的最大深度,剛剛我們將python允許的遞迴深度設定為了10w,至於實際可以達到的深度就取決於計算機的效能了。不過我們還是不推薦修改這個預設的遞迴深度,因為如果用997層遞迴都沒有解決的問題要麼是不適合使用遞迴來解決要麼是你程式碼寫的太爛了

遞迴函式與二分查詢演算法

l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]

你觀察這個列表,這是不是一個從小到大排序的有序列表呀?

如果這樣,假如我要找的數比列表中間的數還大,是不是我直接在列表的後半邊找就行了?

Code 實現:

簡單版二分法

l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]deffunc(l,aim):    mid = (len(l)-1)//2ifl:ifaim > l[mid]:func(l[mid+1:],aim)elif aim < l[mid]:func(l[:mid],aim)elif aim == l[mid]:print("bingo",mid)else:print('找不到')func(l,66)func(l,6)

升級版二分法

def search(num,l,start=None,end=None):start=startifstartelse0end=endifendisNoneelselen(l) -1mid= (end-start)//2+startifstart>end:returnNoneelif l[mid] >num:returnsearch(num,l,start,mid-1)    elif l[mid]