🍊前面的章節,我們學習完了python的基本資料結構:基本資料型別、堆疊、佇列、鏈表、遞回、排序、搜索、樹等,今天我們來學習匿名函式lambda,對往期內容感興趣的同學可以參考👇:
- python資料型別: python資料結構之資料型別.
- python的輸入輸出: python資料結構之輸入輸出、控制和例外.
- python資料結構之面向物件: python資料結構之面向物件.
- python資料結構之演算法分析: python資料結構之演算法分析.
- python資料結構之堆疊、佇列和雙端佇列: python資料結構之堆疊、佇列和雙端佇列.
- python資料結構之遞回: python資料結構之遞回.
- python資料結構之搜索: python資料結構之搜索.
- python資料結構之排序: python資料結構之排序.
- python資料結構之樹: python資料結構之樹.
🌰今天所要學習的匿名函式lambda是宣告函式的另一種方式,可以將簡單的函式用一行代碼來表示,或許是因為lambda所宣告的函式沒有名字,所以lambda被稱為匿名函式(沒有名字的函式)
目錄
- 1. lambda的介紹
- 2.lambda運算式
- 2.1 lambda和def的差別
- 2.2 lambda使用方式
- 2.3 避免使用嵌套
- 3. map函式使用方法
- 4. filter和reduce函式使用方法
- 5.總結
- 6.參考資料
1. lambda的介紹
通常情況下,我們使用def陳述句來定義函式,但python還提供了一種生成函式物件的運算式形式,由于它與LISP語言中的一個工具很相似,所以稱為lambda,就像def一樣,這個運算式創建了一個之后能夠呼叫的函式,但是它回傳了一個函式而不是將這個函式賦值給一個變數名,它們常常以一種行內進行函式定義的形式使用,或者用作推遲執行一些代碼,
2.lambda運算式
lambda的一般形式是關鍵字lambda,之后是一個或多個引數(與一個def頭部內用括號括起來的引數串列極其相似),緊跟的是一個冒號,之后是一個運算式:
lambda argument1,argument2,argument3,...,argumentN:expression using arguments
2.1 lambda和def的差別
由lambda運算式所回傳的函式物件與由def創建并賦值后的函式物件作業起來是完全一樣的,但是lambda有場合比def顯得更方便,更簡潔,
- lambda是一個運算式,而不是一個陳述句,因為這一點,lambda能夠出現在Python語法不允許def出現的地方——例如,在一個串列常量中或者函式呼叫的引數中,此外,作為一個運算式,lambda回傳了一個值(一個新的函式),可以選擇性地賦值給一個變數名,相反,def陳述句總是得在頭部將一個新的函式賦值給一個變數名,而不是將這個函式作為結果回傳,
- lambda的主體是一個單個的運算式,而不是一個代碼塊,這個lambda的主體簡單得就好像放在def主體的return陳述句中的代碼一樣,簡單地將結果寫成一個順暢的運算式,而不是明確的回傳,因為它僅限于運算式,lambda通常要比def功能要小:你僅能夠在lambda主體中封裝有限的邏輯進去,連if這樣的陳述句都不能夠使用,這是有意設計的——它限制了程式的嵌套:lambda是一個為撰寫簡單的函式而設計的,而def用來處理更大的任務,
總而言之,lambda起到了一種函式速寫的作用,允許在使用的代碼內嵌入一個函式的定義,它們完全是可選的(你總是能夠使用def來替代它們),但是在你僅需要嵌入小段可執行代碼的情況下它們會帶來一個更簡潔的代碼結構,
2.2 lambda使用方式
我們使用lambda來創建函式,看一下lambda宣告函式的方式:
#用def宣告一個函式
def fun1(x,y,z):
return x*y*z
fun1(1,2,3)
#用lambda宣告一個函式
f1=lambda x,y,z:x*y*z
f1(1,2,3)
這里的f1被賦值給一個lambda運算式創建的函式物件,這也就是def所完成的任務,只不過def的賦值是自動進行的,
f2=lambda x='he',y='ll',z='o':x+y+z
結果如下:

這說明lambda也可以使用默認的引數,就像在def中設定默認引數一樣,
在一些場合中,比如串列,字典中嵌入函式,但def不會在這些串列或字典中執行,這時候就需要用到lambda
#使用lambda構造一個函式串列
l1=[lambda x:x**2,lambda x:x**3,lambda x:x**4]
for i in l1:#列印結果
print(i(2))
結果如下:

當然l1也可以當作正常串列切片操作:

而def實作該功能,需要在串列外定義三個函式,顯得很繁瑣:
#需要def三個函式
def f1(x):return x**2
def f2(x):return x**3
def f3(x):return x**4
l2=[f1,f2,f3]
for j in l2:
print(j(2))
傳入字典中也是同一樣的道理:
#字典內添加lambda
dict={"name":(lambda x: x-5),"page":(lambda x:x**2),"years":(lambda x:x/2)}
#進行切片操作
dict['name'](10)
結果如下:

2.3 避免使用嵌套
lambda也可以這樣使用:
(lambda x:(lambda y:x+y)(87))(13)
結果如下:

這種嵌套的結構,嵌套的lambda代碼都能夠獲取在上層lambda函式中的變數x,但是這種結構可讀性很差,很令人費解,盡量不要使用這種結構,
3. map函式使用方法
map呼叫與串列決議很相似,但是map對每一個元素都應用了函式呼叫而不是任意的運算式,例如:我們經常對串列和其他序列常常要做的一件事就是對每一個元素進行一個操作并把其結果集合起來,例如,在一個串列counter中更新所有的數字,可以簡單地通過一個for回圈來實作,
#每個元素加10
a=[1,2,3,4]
b=[]
for i in a:
b.append(i+10)
print(b)
使用map函式會對一個序列物件中的每一個元素應用被傳入的函式,并且回傳一個包含了所有函式呼叫結果的一個串列,
#map實作元素加10 第一種方法
def f(x):
return x+10
list(map(f,a))
##map實作元素加10 第二種方法
list(map(lambda x:x+10,a))
結果如下:

因為map是內置函式,它總是可用的,并總是以同樣的方式作業,還有一些性能方面的優勢,簡而言之,它要比自己撰寫的for回圈更快,此外map還可以提供多個序列作為引數:
#求1^1,2^2,3^3次方
list(map(pow,[1,2,3],[1,2,3]))
結果如下:

4. filter和reduce函式使用方法
filter函式主要作用是基于某一測驗函式過濾出一些元素,
#在陣列中挑出大于0的元素
a=range(-5,5)
list(filter(lambda x:x>0,a))
結果如下:
序列中的元素若其回傳值為真的話,將會被鍵入到結果的串列中,
reduce在Python 2.6中只是一個簡單的內置函式,但是在Python 3.0中則位于functools模塊中,需要導包
from functools import reduce
a=[1,2,3,4]
#計算所有序列之和
reduce(lambda x,y:x+y,a)
#計算所有序列之積
reduce(lambda x,y:x*y,a)
結果如下:

每一步,reduce傳遞了當前的和或乘積以及串列中下一個的元素,傳給列出的lambda函式,默認,序列中的第一個元素初始化了起始值,
5.總結
本章節我們主要講述了lambda函式、map函式、filter函式、reduce函式,其中lambda運算式函式可以高效的幫助我們完成一些序列操作的任務,而map,filter,reduce配合lambda使用可以發揮出他們強大的功能,而且這些函式在分布式計算中也有著重要意義,
6.參考資料
《python資料結構與演算法》
《大話資料結構》
《python學習手冊》
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/404350.html
標籤:其他
上一篇:軟體測驗學習初期day06
下一篇:資料結構之前綴樹
