Python匿名函數Lambda
一、概念介紹
1.匿名函數介紹
在Python中,通過lambda關鍵字來定義的函數稱為匿名函數;
lambda函數能接收任何數量(可以是0個)的參數,但只能返回一個表達式的值,lambda函數是一個函數對象,直接賦值給一個變量,這個變量就成了一個函數對象
語法:lambda 參數 : 表達式
先寫lambda關鍵字,然后依次寫匿名函數的參數,多個參數中間用英文逗號分隔,然后是一個英文冒號,冒號后面寫返回的表達式;
2.匿名函數與普通函數的對比
def sum_func(a, b, c):
return a + b + c
sum_lambda = lambda a, b, c: a + b + c
print(sum_func(1, 100, 10000))
print(sum_lambda(1, 100, 10000))
運行結果:
10101
10101
-
可以看到,lambda適用于多個參數、一個返回值的情況,可以用一個變量來接收,變量是一個函數對象,執行這個函數對象的結果與執行一個普通函數的結果一樣。
-
lambda函數比普通函數更簡潔,且沒有聲明函數名,上面的代碼是用一個變量來接收lambda函數返回的函數對象,并不是lambda函數的名字。
3.匿名函數的多種形式
#無參數
lambda_a = lambda :1001
print(lambda_a())
#一個參數
lambda_b = lambda b : b * 10
print(lambda_b(10))
#多個參數
lambda_c = lambda a,b,c : a+b+c
print(lambda_c(5,6,7))
#表達式
lambda_d = lambda x: x if x % 2 ==0 else x+1
print(lambda_d(5))
print(lambda_d(6))
運行結果:
1001
100
18
6
6
lambda的參數可以是0個或多個,并且返回的表達式可以是一個復雜的表達式,只要最后返回的是一個值就可以了;
4.lambda作為一個參數傳遞
def sub_func(a,b,func):
print('a = ',a)
print('b = ',b)
print('a + b = ',func(a,b))
sub_func(12,5,lambda a,b:a+b)
運行結果:
a = 12
b = 5
a + b = 17
5.lambda函數與python內置函數配合使用
list1 = [{'a': 10, 'b': 20}, {'a': 13, 'b': 2}, {'a': 23, 'b': 13}, {'a': 32, 'b': 17}]
max_a = max(list1, key=lambda x: x['a']) # 列表元素中關鍵字'a'的最大值
max_b = max(list1, key=lambda x: x['b']) # 列表元素中關鍵字'b'的最大值
print('列表最大數:', max_a)
print('列表最大數:', max_b)
運行結果:
列表最大數: {'a': 32, 'b': 17}
列表最大數: {'a': 10, 'b': 20}
6.lambda作為函數的返回值
def ret_func(a,b):
return lambda c : a + b + c
return_func = ret_func(50, 51)
print(return_func)
print(return_func(4))
運行結果:
<function ret_func.<locals>.<lambda> at 0x000001711D2B8400>
105
匿名函數可以作為一個函數的返回值,在如上代碼中,ret_func返回的是一個匿名函數,返回的是一個函數對象,當執行這個函數時,可以得到lamdba函數的結果。
注意:其中a,b兩個參數是ret_func中的參數,但執行返回的函數return_func時,已經不在ret_func的作用域內,而lambda函數仍然能使用a,b,參數,說明lambda函數會將它的運行環境保存一份,一直保留到它自己執行的時候使用。
7.匿名函數的優點
- 使用Python寫一些腳本時,使用lambda可以省去定義函數的過程,讓代碼更精簡;
- 對于一些抽象的,不會被別的地方再重復使用的函數,有時候函數起個名稱也是個難題,使用lambda不需要考慮命命名問題;
- 使用lambda在某些時候代碼更容易理解
二、使用場景
使用場景:
1.需要將一個函數對象作為參數來傳遞時,可以直接定義一個lambda函數(作為函數的參數或返回值);
2.要處理的業務符合lambda函數的情況(任意多個參數和一個返回值),并且只有一個地方會使用這個函數,不會在其他地方重用,可以使用lambad函數;
3.與一些python的內置函數配合合適,提高代碼的可讀性;
1、和map函數一起使用
map()函數接收兩個參數,一個是函數,一個是Iterable,map將傳入的函數依次作用到序列的每個元素,并把結果作為新的Iterator返回
遍歷序列,對序列中每個元素進行函數操作,最終獲取新的序列。
案例如下:
求列表[1,2,3,4,5,6,7,8,9],返回一個n*n 的列表
#一般解決方案
li = [1,2,3,4,5,6,7,8,9]
for ind,val in enumerate(li):
li[ind] = val * val
print(li)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
$\textcolor{blue}{enumerate()是python的內置函數, 在字典賞識枚舉、列舉的意思;}$
$\textcolor{blue}{enumerate參數為可遍歷/可迭代的對象(如列表、字符串);}$
$\textcolor{blue}{enumerate多用于在for循環中得到計數,利用它可以同時獲得索引和值,即需要 index 和 value 值的時候可以使用enumerate;}$
$\textcolor{blue}{enumerate()返回的是一個enumerate對象 。}$
#高級解決方案
li = [1,2,3,4,5,6,7,8,9]
print(list(map(lambda x:x*x,li)))
[1, 4, 9, 16, 25, 36, 49, 64, 81]
2、與reduce函數一起使用
reduce把一個函數作用在一個序列[x1, x2, x3, ...]上,這個函數必須接收兩個參數,reduce把結果繼續和序列的下一個元素做累積計算,其效果就是:
reduce(func,[1,2,3]) 等同于 func(func(1,2),3),返回值為單個值
對于序列內所有元素進行累計操作
#接受一個list并利用reduce()求積
from functools import reduce
li = [1,2,3,4,5,6,7,8,9]
print(reduce(lambda x,y:x * y,li))
結果 : 123456789 = 362880
a = [12, 34, 56]
print reduce(lambda x , y: x + y, a) # 102
print reduce(lambda x , y: x - y, a) # -78
3、和filter函數一起使用
filter()也接收一個函數和一個序列。和map()不同的是,filter()把傳入的函數依次作用于每個元素,然后根據返回值是True還是False決定保留還是丟棄該元素。
對于序列中的元素進行篩選,最終獲取符合條件的序列
在一個list中,刪掉偶數,只保留奇數
li = [1, 2, 4, 5, 6, 9, 10, 15]
print(list(filter(lambda x:x % 2==1,li))) # [1, 5, 9, 15]
回數是指從左向右讀和從右向左讀都是一樣的數,例如12321,909。請利用filter()篩選出回數
li = list(range(1, 200))
print(list(filter(lambda x:int(str(x))==int(str(x)[::-1]),li)))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151, 161, 171, 181, 191]
4、和sorted函數一起使用
sorted(iterable, /, *, key=None, reverse=False)
接收一個key函數來實現對可迭代對象進行自定義的排序
可迭代對象:主要與列表,字符串,元祖,集合和字典
key:接受一個函數,根據此函數返回的結果,進行排序
reverse:排序方向,默認為從小到大,reverse=True為逆向
對列表按照絕對值進行排序
li= [-21, -12, 5, 9, 36]
print(sorted(li, key = lambda x:abs(x)))
[5, 9, -12, -21, 36]
"""
sorted()函數按照keys進行排序,并按照對應關系返回list相應的元素:
keys排序結果 => [5, 9, 12, 21, 36]
| | | | |
最終結果 => [5, 9, -12, -21, 36]
"""
把下面單詞以首字母排序
li = ['bad', 'about', 'Zoo', 'Credit']
print(sorted(li, key = lambda x : x[0]))
輸出['Credit', 'Zoo', 'about', 'bad']
"""
對字符串排序,是按照ASCII的大小比較的,由于'Z' < 'a',結果,大寫字母Z會排在小寫字母a的前面。
"""
假設我們用一組tuple表示學生名字和成績:
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
請用sorted()對上述列表分別按名字排序
print(sorted(L, key = lambda x : x[0]))
輸出[('Adam', 92), ('Bart', 66), ('Bob', 75), ('Lisa', 88)]
再按成績從高到低排序
print(sorted(L, key = lambda x : x[1], reverse=True))
輸出[('Adam', 92), ('Lisa', 88), ('Bob', 75), ('Bart', 66)]
5、與三元運算結合
如下:
#if 條件為真的時候返回if前面內容,否則返回0
exp1= lambda x:x+1 if 2==1 else 0
print(exp1(2))
exp2 = lambda x:x+1 if 1==1 else 0
print(exp2(2))
輸出:
0
3
#if not 為假返回if not前面內容,否則返回0
exp3 = lambda x:x+1 if not 2==1 else 0
print(exp3(2))
exp4 = lambda x:x+1 if not 1==1 else 0
print(exp4(2))
輸出:
3
0
浙公網安備 33010602011771號