python之lambda表達式與sort函數(shù)中的key用法
python lambda表達式與sort函數(shù)中的key
lambda表達式
lambda 表達式常用來聲明匿名函數(shù),也就是沒有函數(shù)名字的、臨時使用的小函數(shù),常用在臨時需要一個類似于函數(shù)的功能但又不想定義函數(shù)的場合。
例如,內(nèi)置函數(shù)sorted()和列表方法sort()的 key參數(shù),內(nèi)置函數(shù)map()和filter()的第一個參數(shù)等。當然,也可以使用lambda表達式定義具名函數(shù)。
lambda表達式只可以包含一個表達式,不允許包含復雜語句和結(jié)構(gòu),但在表達式中可以調(diào)用其他函數(shù),該表達式的計算結(jié)果相當于函數(shù)的返回值。
下面的代碼演示了不同情況下 lambda表達式的應用。
簡言之:
lambda表達式就是函數(shù)的迷你版,如果定義的函數(shù)比較簡單可以使用lambda代替。
>>> def func(a,b,c): ?? ?return a+b+c >>> f = lambda a,b,c:a+b+c ?# 與func函數(shù)等價 >>> f(1,2,3) # 輸出6 >>> s = lambda a,b=5,c=1:a+b+c ?# 支持默認參數(shù) >>> s(8) ?# 輸出14 >>> s = "abcde" >>> tuple(map(lambda x:x.upper(),s)) ?# lambda 也可以作為函數(shù)參數(shù) ('A', 'B', 'C', 'D', 'E')
咳咳,我說一下map函數(shù),真的太頂了。它有兩個參數(shù)嘛,第二個參數(shù)是一個可迭代對象,列表,元組,字符串,集合,字典那些,第一個參數(shù)一般就是一個功能函數(shù)來的,map函數(shù)大概就是,將迭代對象里面的每一個元素都傳那個功能函數(shù)進行處理,以上面例子為例,將字符串s里面的每一個小寫元素通過lambda表達式函數(shù)轉(zhuǎn)換為大寫,存到map對象里面,如果要看結(jié)果的話要用list,tuple這些數(shù)據(jù)類型將其強制轉(zhuǎn)換出來顯示,不然看不到。
sort函數(shù)
最后就是經(jīng)典的與sort函數(shù)搭配了。
假設有一個二維列表,我們以第二維元素值的大小對列表進行排序。
那么他的寫法應該是這樣的。
>>> a = [[1,4],[2,3],[5,1]] >>> a [[1, 4], [2, 3], [5, 1]] >>> sorted(a,key=lambda x:x[1]) ? # 用sorted是不想修改a [[5, 1], [2, 3], [1, 4]] ? ? # 可以看到生成了按嵌套列表中第二個元素排序的列表
或許有些讀者跟我剛才一樣,知道這樣寫,但不知道怎么來的。于是我特地找了一些資料,大概的用法就是如果指定key的話就會先遍歷一遍可迭代對象,得到每個元素的key值,然后根據(jù)這個key值進行排序。
相當于 for i in a,然后指定對i的某種操作,當然,要寫成函數(shù)的形式才行。
如果寫成一般函數(shù)的話是這種形式。
>>> a = [[1,4],[2,3],[5,1]] >>> def func(nums): ?# 這里的nums相當于是a中的每個元素 也就是[1,4],[2,3],[5,1] ?? ?return nums[1] # 注意注意!這里要格外注意,這里的key中func沒有括號沒有參數(shù)只有名字,相當于就是將a中的每個元素[1,4],[2,3],[5,1]分別去調(diào)用func函數(shù)得到一個key值,最后根據(jù)這個k值進行排序。 >>> sorted(a,key=func) ? [[5, 1], [2, 3], [1, 4]]
當我們大概知道了這個sort如何排序之后,其他多騷的寫法都能寫得出來,現(xiàn)在我們就試試。
>>> def func(string): ? # 定義一個函數(shù) ?? ??? ?res = len(set(string)) ? ?# ?首先計算這個單詞有多少個字母 如“aaabb”算兩個字母 ?? ??? ?for i in string: ?? ??? ??? ?if i.isupper(): ?# 如果是大寫 ?? ??? ??? ??? ?res *=1.15 * ord(i) ?# ord表示 i 在 ASCII 對應的值 ?? ??? ??? ?else: ?? ??? ??? ??? ?res*=1.05 * ord(i) ?? ??? ?return res? >>> a = "haHASHSADHn IamaHandsomeBoy ?SLSKJlkjSLSjGHUh ?iljEILNGLKD".split() >>> sorted(a,key=func) ?# 記住不要括號 ['haHASHSADHn', 'iljEILNGLKD', 'IamaHandsomeBoy', 'SLSKJlkjSLSjGHUh']
騷寫法寫得出來,簡單的寫法就迎刃而解了。當然,使用lambda表達式前提是你對排序的定義足夠簡單,就是按哪個哪個排序的。復雜一點的話就要像上面一樣自定義函數(shù)了。
下面看一下使用lambda對字典以值(值噢,而不是鍵)進行排序。
>>> a {1: 5, 2: 3, 7: 6, 5: 2} >>> sorted(a) ?# 如果直接寫的話只會對鍵排序,沒有達到我們想要的效果。 [1, 2, 5, 7] >>> a.sort() ? # 如果直接使用sort會報錯,因為字典沒有這個函數(shù) Traceback (most recent call last):? ? File "<pyshell#47>", line 1, in <module> ? ? a.sort() AttributeError: 'dict' object has no attribute 'sort' >>> sorted(a.items(),key=lambda x:x[1]) ?# 因為鍵值我們都要,所以要使用a.items(),然后以每個元素的第二個值作為key值進行排序,得到下面的結(jié)果 [(5, 2), (2, 3), (1, 5), (7, 6)] ? ?# 我們想要的應該是排序后的字典,而這個還不是,但是有點像,我們可以直接使用dict函數(shù)強制轉(zhuǎn)換成字典。 >>> dict(sorted(a.items(),key=lambda x:x[1])) {5: 2, 2: 3, 1: 5, 7: 6} ? # 搞定
python匿名函數(shù)lambda表達式與sort()、sorted()、min()、max()、map()、reduce()、filter()使用
1. 什么是匿名函數(shù)
匿名函數(shù),即沒有函數(shù)名稱的函數(shù)。學過Python的都知道,Python中函數(shù)的定義格式為:(關鍵字)def(加)(函數(shù)名)get_name:(函數(shù)體),但是匿名函數(shù)沒有函數(shù)名稱,它的定義格式為:lambda [arg1,[arg2,arg3…]]: expression,因此匿名函數(shù)又被成為lambda表達式,它只包含一行表達式。
2. lambda表達式
定義格式:lambda [arg1,[arg2,arg3…]]: expression,其中l(wèi)ambda為必須的關鍵字,args表示參數(shù)列表,expression表示表達式。
為便于理解,該語法格式轉(zhuǎn)為普通函數(shù)格式如下:
def fun_name(arg1,[arg2,arg3..]): return expression fun_name(arg1,[arg2,arg3..])
顯然,使用普通方法定義此函數(shù),需要 3 行代碼,而使用 lambda 表達式僅需 1 行。
舉個例子:
def square(x): return x ** 2 print(square(5)) # 此處只是為了舉例,平常不建議這樣將lambda表達式賦值給變量 a = lambda x: x ** 2 print(a(5))
運行結(jié)果
25
25
3. lambda表達式的用途
lambda表達式只有一行,相比于函數(shù),它具有的優(yōu)勢:
- 對于單行函數(shù),使用 lambda 表達式可以省去定義函數(shù)的過程,讓代碼更加簡潔;
- 對于不需要多次復用的函數(shù),使用 lambda 表達式可以在用完之后立即釋放,提高程序執(zhí)行的性能。
那么,lambda表達式的使用方式有哪些呢:
1.排序,結(jié)合sorted() 和sort()方法使用
# 方式1 list1 = [1, 2, 6, 9, 3, 5, 4, 0] list1.sort(key=lambda x: x) # lambda x: x中第一個x為參數(shù),此時是list1中的每個元素,第二個x是表達式,此時也表示list1中的每個元素 # 通過在第二行打斷點,然后調(diào)試運行,會發(fā)現(xiàn)表達式x,會被依次賦值為列表 # list1中的每個值 print(list1) # 方式2 # list2 中記錄名字和他的年齡 list2 = [['小明', 23], ['大美', 22], ['小帥', 18], ['張三', 24]] list3 = sorted(list2, key=lambda x: x[1]) # lambda x: x[1]中第一個x為參數(shù),此時是list2中的每個元素,此時是列表, # 即'['小明', 23]';第二個x[1]是表達式,此時表示列表中第二個值,即23 # 表示按照每個人的年齡排序 print(list3) # 方式3 list4 = ['3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'] t = ['3', '3', '4', '6', '5', '8', '7', '10', '10', 'K', 'A', 'J', 'Q'] t.sort(key=lambda x: list4.index(x)) # lambda x: list4.index(x)中第一個x為參數(shù),此時是t中的每個元素 # list4.index(x)是表達式,表示x在list4中的索引值,表示按照索引值大小排序 print(t)
輸出結(jié)果:
[0, 1, 2, 3, 4, 5, 6, 9]
[[‘小帥’, 18], [‘大美’, 22], [‘小明’, 23], [‘張三’, 24]]
[‘3’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘10’, ‘10’, ‘J’, ‘Q’, ‘K’, ‘A’]
2.結(jié)合max()、min()使用
list2 = [['小明', 23], ['大美', 22], ['小帥', 18], ['張三', 24]] list5 = [2, 10, 4, 3, 1, 2, 6, 8, 7] res = max(list5, key=lambda x: x) print(res) name_age = min(list2, key=lambda x: x[1]) print(name_age)
輸出結(jié)果:
10
[‘小帥’, 18]
3.結(jié)合map()函數(shù)使用
# ===========一般寫法:=========== # 1、計算平方數(shù) list6 = [2,3,6,1,5] def square(x): return x ** 2 s = list(map(square, list6)) # 計算列表各個元素的平方 print(s) # ===========匿名函數(shù)寫法:============ # 2、計算平方數(shù),lambda 寫法 s1 = list(map(lambda x: x ** 2, list6)) print(s1) # 3、提供兩個列表,將其相同索引位置的列表元素進行相加 list7 = [1,2,34,6] s2 = list(map(lambda x, y: x + y, list7, list6)) print(s2)
輸出結(jié)果:
[4, 9, 36, 1, 25]
[4, 9, 36, 1, 25]
[3, 5, 40, 7]
4.結(jié)合reduce()使用
reduce函數(shù)是Python中的內(nèi)置函數(shù),用于計算可迭代對象的累積結(jié)果。
reduce 函數(shù)的用法和示例:
reduce(function, iterable[, initializer])
- 函數(shù)定義:對可迭代對象中的元素進行累積操作,返回一個單一的結(jié)果。
- 參數(shù) function:用于累積操作的函數(shù),接受兩個參數(shù),必須返回一個值。
- 參數(shù) iterable:可迭代對象,包含要進行累積操作的元素。
- 參數(shù) initializer:可選參數(shù),作為累積的初始值。如果提供了初始值,則累積操作從初始值開始;如果未提供初始值,則累積操作從可迭代對象的第一個元素開始。
from functools import reduce list8 = [5, 6, 7, 4, 3, 2, 1] # 此時初始值默認為列表第一個元素,計算元素的和 s3 = reduce(lambda x, y: x + y, list8) print(s3) # 定義初始值為0,計算列表元素的平方和 s4 = reduce(lambda x, y: x + y ** 2, list8, 0) print(s4) # 計算n的階乘 n = 5 s5 = reduce(lambda x, y: x * y, range(1, n + 1)) print(s5) # 計算最大值 s6 = reduce(lambda x, y: x if x > y else y, list8) print(s6)
輸出結(jié)果:
28
140
120
7
5.結(jié)合filter()使用
filter函數(shù)用于過濾序列,過濾掉不符合條件的元素
filter(function, iterable)
function
:用于過濾的函數(shù)iterable
:可迭代對象
list9 = [1, 2, 3, 4, 5, 6, 7, 8] # 保留偶數(shù) s7 = list(filter(lambda x: x % 2 == 0, list9)) print(s7)
輸出結(jié)果:
[2, 4, 6, 8]
心得:
1.lambda表達式可直接賦值給變量
2.lambda表達式可結(jié)合函數(shù)使用,若函數(shù)中帶有參數(shù)key或這參數(shù)function,如sort()、sorted()、min()、max()、map()、reduce()、filter()等
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Python實現(xiàn)接口下載json文件并指定文件名稱
在 Web 開發(fā)中,提供文件下載功能是一種常見的需求,尤其是當涉及到導出數(shù)據(jù)為 JSON 格式時,為了確保文件名的自定義以及避免亂碼問題,開發(fā)者需要采取一些特定的措施,本文介紹了Python實現(xiàn)接口下載json文件并指定文件名稱,需要的朋友可以參考下2024-10-10python庫patchworklib多圖表整合用法示例探究
這篇文章主要介紹了python庫patchworklib對齊matplotlib圖表,將多個圖表的整合為單一圖表用法示例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2024-01-01詳解在Python的Django框架中創(chuàng)建模板庫的方法
這篇文章主要介紹了在Python的Django框架中創(chuàng)建模板庫的方法,模版庫通常用來管理單獨的Django中的應用,需要的朋友可以參考下2015-07-07