摘要:什么是推導(dǎo)式大家好,今天為大家?guī)?lái)問(wèn)我最喜歡的推導(dǎo)式使用指南,讓我們先來(lái)看看定義推導(dǎo)式是的一種獨(dú)有特性,推導(dǎo)式是可以從一個(gè)數(shù)據(jù)序列構(gòu)建另一個(gè)新的數(shù)據(jù)序列的結(jié)構(gòu)體。
什么是推導(dǎo)式
大家好,今天為大家?guī)?lái)問(wèn)我最喜歡的Python推導(dǎo)式使用指南,讓我們先來(lái)看看定義~
推導(dǎo)式(comprehensions)是Python的一種獨(dú)有特性,推導(dǎo)式是可以從一個(gè)數(shù)據(jù)序列構(gòu)建另一個(gè)新的數(shù)據(jù)序列的結(jié)構(gòu)體。一般有三種使用最多的推導(dǎo)式:
列表推導(dǎo)式(list comprehensions)
字典推導(dǎo)式(dict comprehensions)
集合推導(dǎo)式(set comprehensions)
使用推導(dǎo)式可以簡(jiǎn)化代碼的同時(shí)提高效率,在我的個(gè)人使用場(chǎng)景中,用的最多的還是列表推導(dǎo)式,接下來(lái)我會(huì)一一介紹這三種常見(jiàn)的推導(dǎo)式,最后通過(guò)一個(gè)簡(jiǎn)單實(shí)戰(zhàn)發(fā)現(xiàn)推導(dǎo)式的高效之處
列表推導(dǎo)式(list comprehensions)模板
首先,讓我們看看使用列表推導(dǎo)式的基礎(chǔ)模板:
[ expression for item in list if conditional ]
簡(jiǎn)單來(lái)說(shuō),遍歷一個(gè)list,得到每一個(gè)元素item,我們相對(duì)item進(jìn)行哪些操作,寫(xiě)在expression里就可以,如果對(duì)篩選有什么條件,可以放在if后面
下面可以通過(guò)大量實(shí)例幫助大家理解
使用實(shí)例
先看第一個(gè)小栗子,在這里我們用for循環(huán)常規(guī)遍歷一個(gè)字符串‘human’,把每一字母作為元素放在一個(gè)叫h_letters的數(shù)組里面:
h_letters = [] for letter in "human": h_letters.append(letter) print(h_letters) Out:["h", "u", "m", "a", "n"]
如果我們根據(jù)列表推導(dǎo)式的定義模板,可以簡(jiǎn)化如下:
h_letters = [ letter for letter in "human" ] print( h_letters) Out: ["h", "u", "m", "a", "n"]
這樣的話便捷了很多,看上去也很容易理解,這里我們?cè)趀xpression部分什么都沒(méi)有寫(xiě),只是提出了每個(gè)元素而已,運(yùn)行時(shí)的python執(zhí)行方式如下:
我們可以在expression的部分進(jìn)行很多操作,比如:
h_letters = [ letter.upper() for letter in "human" ] print( h_letters) Out: ["H", "U", "M", "A", "N"]
這樣我們可以很容易的實(shí)現(xiàn)字母的大小寫(xiě)轉(zhuǎn)化
同樣的,我們可以在if后面寫(xiě)出篩選條件,比如這里,我們想要提出從-20 ~ 20中所有能被3整除的正數(shù):
result = [num for num in range(-20,20) if num %3==0 and num > 0] print(result) #多個(gè)條件可以用and連接 Out: [3, 6, 9, 12, 15, 18]
列表推導(dǎo)式的實(shí)際應(yīng)用場(chǎng)景十分廣泛,它和lambda不同,是真正好理解,提高效率的python特性之一,這里相信聰明的你已經(jīng)想到了更多用法!
字典推導(dǎo)式(dict comprehensions)模板
讓我們看先來(lái)看使用字典推導(dǎo)式的基礎(chǔ)模板:
{ key:value for key,value in existing_data_structure }
這里和list有所不同,因位dict里面有兩個(gè)關(guān)鍵的屬性,key 和 value,但大同小異,我們現(xiàn)在的expression部分可以同時(shí)對(duì) key 和 value 進(jìn)行操作
下面來(lái)看最常見(jiàn)的應(yīng)用
使用實(shí)例
首先最實(shí)用的功能莫過(guò)于可以實(shí)現(xiàn)一個(gè)dict的key,value值互換:
person = {"name":"xiaobai","city":"paris"} person_reverse = {v:k for k,v in person.items()} #簡(jiǎn)單互換key和value的值即可 print(person_reverse) Out: {"xiaobai": "name", "paris": "city"}
這里就非常方便了用字典推導(dǎo)式,不然的話如果用for循環(huán),會(huì)稍微麻煩一些。
讓我們?cè)倏聪乱粋€(gè)很巧的例子:
nums = {"a":10,"b":20,"A":5,"B":3,"d":4} num_frequency = {k.lower():nums.get(k.lower(),0) + nums.get(k.upper(),0) for k in nums.keys() } print(num_frequency) Out: {"a": 15, "b": 23, "d": 4}
這里使用的就比較靈活,我們有一個(gè)數(shù)據(jù),key是字母的大小寫(xiě)混在一起,我們想統(tǒng)計(jì)同一個(gè)key(大小寫(xiě)都包括)所對(duì)應(yīng)的數(shù)字出現(xiàn)總和,所以在新建的num_frequency 字典用使用了推導(dǎo)式,這里我們遍歷的是dict.keys()配合dict.get()方法,當(dāng)然,如果僅僅是為了實(shí)現(xiàn)這個(gè)功能,我們有更好的辦法,這里只是為了介紹推導(dǎo)式
再比如下面的例子:
fruit = ["apple","banana","organge","mango","peach"] fruit_len = {f:len(f) for f in fruit} print(fruit_len) Out:{"apple": 5, "banana": 6, "organge": 7, "mango": 5, "peach": 5}
我們有一個(gè)fruit的list,現(xiàn)在想要得到每一種水果的單詞長(zhǎng)度,就可以通過(guò)圖中所示的方法實(shí)現(xiàn),非常容易
最后再來(lái)看一個(gè)字典推導(dǎo)式配合枚舉(enumerate)的例子:
fruit = ["apple","organge","banana","mango","peach"] fruit_positon = {v:i for i,v in enumerate(fruit)} print(fruit_positon) Out: {"apple": 0, "organge": 1, "banana": 2, "mango": 3, "peach": 4}
還是用剛才的list,這次我們得到的key是fruit的每個(gè)元素,value則是該元素在fruit所在的index
集合推導(dǎo)式(Set comprehensions)模板
讓我們看先來(lái)看使用集合推導(dǎo)式的基礎(chǔ)模板:
{ expression for item in Sequence if conditional }
其實(shí)集合推導(dǎo)式和list的推導(dǎo)式很像,但是既然是集合,肯定會(huì)配合利用Set的特有屬性來(lái)實(shí)現(xiàn)我們的目的,如果你還對(duì)Set這種數(shù)據(jù)結(jié)構(gòu)不夠了解,可以參考我之前的文章:Python 進(jìn)階之路 (四) 先立Flag, 社區(qū)最全的Set用法集錦
下面來(lái)看最常見(jiàn)的應(yīng)用
使用實(shí)例
首先,我們來(lái)看一個(gè)根據(jù)Set值唯一的特性的例子,我們有一個(gè)list叫names,用來(lái)存儲(chǔ)名字,其中的數(shù)據(jù)很不規(guī)范,有大寫(xiě),小寫(xiě),還有重復(fù)的,我們想要去重并把名字的格式統(tǒng)一為首字母大寫(xiě),實(shí)現(xiàn)方法便是用Set推導(dǎo)式:
names = [ "Bob", "JOHN", "alice", "bob", "ALICE", "James", "Bob","JAMES","jAMeS" ] names_standard = { n[0].upper()+n[1:].lower() for n in names} print(names_standard) Out: {"John", "Bob", "James", "Alice"}
這里就不再舉很多的其他例子了,因?yàn)槭褂玫姆绞蕉喾N多樣,剩下的就靠廣大人民群眾的智慧自行開(kāi)發(fā)即可!
簡(jiǎn)單實(shí)戰(zhàn)現(xiàn)在讓我們來(lái)看一個(gè)比較綜合的例子!我們現(xiàn)在手里有一個(gè)英文字典的dictionary.txt文件,包含從A~Z的單詞
具體需求:我們想要找到長(zhǎng)度大于5的正反拼寫(xiě)都具有實(shí)際含義的單詞
我們現(xiàn)在會(huì)通過(guò)各種推導(dǎo)式來(lái)實(shí)現(xiàn)這個(gè)目標(biāo),我會(huì)在文章最后把txt文件及Python文件下載鏈接附上,這樣大家如果先要練習(xí)可以自行下載
首先,我們的初始目錄結(jié)構(gòu)如下:
這里我新建了一個(gè)test文件夾,把dictionary.txt 文件和python文件放在一起方便讀取,開(kāi)始之前,先大概看下txt文件長(zhǎng)什么樣子:
第一步:讀取dictionary.txt中的單詞,選出長(zhǎng)度大于5的
with open("dictionary.txt") as dictionary_file: words = (line.rstrip() for line in dictionary_file) words_over_five_letters = [w for w in words if len(w)>5 ]
這里通過(guò)列表推導(dǎo)式words_over_five_letters 用來(lái)存儲(chǔ)所有長(zhǎng)度大于5的單詞
第二步:將上一步選出的單詞全部以倒序的方式存儲(chǔ)在一個(gè)集合里
reversed_words ={ word[::-1] for word in words_over_five_letters }
通過(guò)set推導(dǎo)式來(lái)實(shí)現(xiàn)
第三步:通過(guò) if 條件篩選得出結(jié)果
reversible_words = [ word for word in words_over_five_letters if word in reversed_words ] for word in reversible_words[0:20]: print(word) Out: abrood agenes amaroid amunam animal animes bruted darter decart decurt deedeed deflow degami degener degged deified deifier deliver denier
這里最后共有203個(gè)結(jié)果,我們只看了前20個(gè),驗(yàn)證方法就是只要長(zhǎng)度大于5的單詞同時(shí)存在于reversed_words和words_over_five_letters即可
完整代碼如下:
with open("dictionary.txt") as dictionary_file: words = (line.rstrip() for line in dictionary_file) words_over_five_letters = [w for w in words if len(w)>5 ] reversed_words ={ word[::-1] for word in words_over_five_letters } reversible_words = [ word for word in words_over_five_letters if word in reversed_words ] for word in reversible_words[0:20]: print(word)
資料下載
dictionary.txt
dictionary.py
總結(jié)這次為大家總結(jié)了python里面常見(jiàn)的三種推導(dǎo)式相關(guān)用法以及最后的小實(shí)戰(zhàn)環(huán)節(jié),希望大家喜歡,雙擊666點(diǎn)個(gè)贊吧??!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/43214.html
摘要:哪吒社區(qū)技能樹(shù)打卡打卡貼函數(shù)式接口簡(jiǎn)介領(lǐng)域優(yōu)質(zhì)創(chuàng)作者哪吒公眾號(hào)作者架構(gòu)師奮斗者掃描主頁(yè)左側(cè)二維碼,加入群聊,一起學(xué)習(xí)一起進(jìn)步歡迎點(diǎn)贊收藏留言前情提要無(wú)意間聽(tīng)到領(lǐng)導(dǎo)們的談話,現(xiàn)在公司的現(xiàn)狀是碼農(nóng)太多,但能獨(dú)立帶隊(duì)的人太少,簡(jiǎn)而言之,不缺干 ? 哪吒社區(qū)Java技能樹(shù)打卡?【打卡貼 day2...
摘要:新年快樂(lè)大家好,今天是大年初二,身在國(guó)外沒(méi)有過(guò)年的氛圍,只能踏實(shí)寫(xiě)寫(xiě)文章,對(duì)社區(qū)做點(diǎn)貢獻(xiàn),在此祝大家新年快樂(lè)上一期為大家梳理了一些的進(jìn)階用法,今天我們來(lái)看字典的相關(guān)技巧,我個(gè)人在編程中對(duì)字典的使用非常頻繁,其實(shí)對(duì)于不是非常大的數(shù)據(jù)存儲(chǔ)需求, 新年快樂(lè) 大家好,今天是大年初二,身在國(guó)外沒(méi)有過(guò)年的氛圍,只能踏實(shí)寫(xiě)寫(xiě)文章,對(duì)社區(qū)做點(diǎn)貢獻(xiàn),在此祝大家新年快樂(lè)!上一期為大家梳理了一些List的進(jìn)...
摘要:基礎(chǔ)問(wèn)題的的性能及原理之區(qū)別詳解備忘筆記深入理解流水線抽象關(guān)鍵字修飾符知識(shí)點(diǎn)總結(jié)必看篇中的關(guān)鍵字解析回調(diào)機(jī)制解讀抽象類與三大特征時(shí)間和時(shí)間戳的相互轉(zhuǎn)換為什么要使用內(nèi)部類對(duì)象鎖和類鎖的區(qū)別,,優(yōu)缺點(diǎn)及比較提高篇八詳解內(nèi)部類單例模式和 Java基礎(chǔ)問(wèn)題 String的+的性能及原理 java之yield(),sleep(),wait()區(qū)別詳解-備忘筆記 深入理解Java Stream流水...
摘要:基礎(chǔ)問(wèn)題的的性能及原理之區(qū)別詳解備忘筆記深入理解流水線抽象關(guān)鍵字修飾符知識(shí)點(diǎn)總結(jié)必看篇中的關(guān)鍵字解析回調(diào)機(jī)制解讀抽象類與三大特征時(shí)間和時(shí)間戳的相互轉(zhuǎn)換為什么要使用內(nèi)部類對(duì)象鎖和類鎖的區(qū)別,,優(yōu)缺點(diǎn)及比較提高篇八詳解內(nèi)部類單例模式和 Java基礎(chǔ)問(wèn)題 String的+的性能及原理 java之yield(),sleep(),wait()區(qū)別詳解-備忘筆記 深入理解Java Stream流水...
閱讀 2183·2021-10-08 10:21
閱讀 2657·2021-09-29 09:34
閱讀 3570·2021-09-22 15:51
閱讀 5087·2021-09-22 15:46
閱讀 2370·2021-08-09 13:42
閱讀 3502·2019-08-30 15:52
閱讀 2795·2019-08-29 17:13
閱讀 1620·2019-08-29 11:30