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