Python小知识:推导式用法大全,Comprehension
「推導(dǎo)式」的英文是「Comprehension」,是Python學(xué)習(xí)者引以為豪的一種寫法。它的主要好處是「寫起來簡(jiǎn)潔」,不用for循環(huán),非常的「Pythonic」。
它包括「列表推導(dǎo)式」,「字典推導(dǎo)式」,「集合推導(dǎo)式」,還有「生成器推導(dǎo)式」等。推導(dǎo)過程可以使用「條件推導(dǎo)」,或者在推導(dǎo)表達(dá)式中應(yīng)用「分支語句」,非常靈活。
本文核心內(nèi)容之前發(fā)過,這次作為Python終結(jié)者系列重發(fā)一次,也做了一些補(bǔ)充。
熟練使用本文中的樣例代碼,就基本全面掌握了推導(dǎo)式的知識(shí)。建議把文中代碼多練習(xí)幾次。
1 基本推導(dǎo)式
寫一段代碼生成1到100之間的數(shù)字的平方的列表,答案是:
1,4,9,16...如果你這樣寫,你就不Pythonic了:
nums = [] for i in range(1,101):nums.append(i*i) print(nums)正確的寫法是使用Python的推導(dǎo)式:
nums = [i*i for i in range(1,101)]上面的推導(dǎo)式有3個(gè)關(guān)鍵點(diǎn):
- 「for循環(huán)」,其中包含被循環(huán)的range對(duì)象和代表當(dāng)前變量的i
- i * i 是推導(dǎo)「表達(dá)式」,表示根據(jù)for循環(huán)中的i推導(dǎo)出i * i
- 整個(gè)表達(dá)式用「方括號(hào)」表示推導(dǎo)的結(jié)果生成一個(gè)列表
2 帶條件的推導(dǎo)式
推導(dǎo)式也可以添加條件,這讓推導(dǎo)式的應(yīng)用更加廣泛。
生成一個(gè)列表,包含1到100之間是3的倍數(shù)的數(shù)字的平方:
9,36,81...代碼:
nums = [i*i for i in range(1,101) if i%3==0]這樣把推導(dǎo)式的3個(gè)要素變成了4個(gè):
- for循環(huán)
- 表達(dá)式 i * i
- 推導(dǎo)套件 if i % 3 == 0
- 方括號(hào)
注意這些要素的順序不能變化
3 在推導(dǎo)表達(dá)式中應(yīng)用分支語句
推導(dǎo)式不光可以用if,還可以用else。
生成一個(gè)列表,如果是3的倍數(shù)就用平方,否則就用是數(shù)字本身:
1,2,9,4,5,36...代碼:
nums = [i*i if i%3==0 else i for i in range(1,101)]注意帶分支的情況下,if…else寫在了for循環(huán)的左邊,它的實(shí)際過程是:
- 對(duì)整個(gè)range進(jìn)行推導(dǎo)
- 在推導(dǎo)過程中用if…else決定輸入出什么
這和前面的if推導(dǎo)式是不同的
結(jié)合上面的3個(gè)例子,來看一下推導(dǎo)式總結(jié):
1.推導(dǎo)式從一個(gè)可枚舉數(shù)據(jù)(列表,元組,集合,字典等)推導(dǎo)出一個(gè)列表。也可以推導(dǎo)出生成器,集合或字典。
2.推導(dǎo)式可以加推導(dǎo)條件,只對(duì)符合條件的元素推導(dǎo)
3.要推導(dǎo)出的元素使用表達(dá)式生成,可以用if else生成不同元素
[表達(dá)式 if 表達(dá)式條件 else 分支 for i in 序列 if 推導(dǎo)條件]4 在推導(dǎo)式中使用函數(shù)
如果推導(dǎo)條件或者表達(dá)式特別復(fù)雜怎么辦?可以使用函數(shù)。
推導(dǎo)所有1-100之間的所有質(zhì)數(shù):2,3,5,7…
def is_prime(num):if num == 1:return False for i in range(2,num):if (num % i) == 0:return Falseelse:return Truep_nums = [i for i in range(1,100) if is_prime(i)] print(p_nums)把推導(dǎo)的條件放在函數(shù)中,既可以應(yīng)對(duì)復(fù)雜的條件,又可以利用推導(dǎo)式的簡(jiǎn)潔寫法。
同理,如果生成推導(dǎo)結(jié)果的過程很復(fù)雜,也可以把邏輯放到函數(shù)中。
推導(dǎo)1900到2021年之間所有的年份,標(biāo)記出閏年,生成結(jié)果:
1900, 1901, 1902, 1903, '閏1904'代碼:
def is_run(year):if (year % 4) == 0:if (year % 100) == 0:if (year % 400) == 0:return True # 整百年能被400整除的是閏年else:return Falseelse:return True # 非整百年能被4整除的為閏年else:return False ryears = [f'閏{y}' if is_run(y) else y for y in range(1900, 2021)] print(ryears)5 推導(dǎo)式中嵌套推導(dǎo)式
從2000年到2021年,生成每個(gè)月份:‘2000年:1月’, ‘2000年:2月’, ‘2020年:3月’, …, ‘2021年:12月’
monthes = [f'{y}年:{m}月' for y in range(2000, 2022) for m in range(1,13) ]這里有兩個(gè)for循環(huán),類似于:
monthes = [] for y in range(2000, 2022):for m in range(1,13):monthes.append(f'{y}年:{m}月')是不是下面的特別容易懂?所以兩層的循環(huán)不推薦使用推導(dǎo)式,哈哈。
那我為什么還要講?你會(huì)碰到有人這么寫,知道它的存在還是有點(diǎn)必要的。
6 推導(dǎo)巨大的列表 - 不要這么干!
推導(dǎo)出1到100億之間的數(shù)字的平方,代碼如下:
nums = [i*i for i in range(1,10000000000)]但是這段代碼很可能會(huì)卡死你的電腦,除非你的電腦是超級(jí)計(jì)算機(jī)。因?yàn)樗趦?nèi)存中做100億次計(jì)算,然后保存這100億個(gè)數(shù)字。
正確的做法是使用生成器推導(dǎo)式。
7 生成器推導(dǎo)式
這種情況下,我們應(yīng)該使用推導(dǎo)生成器,用法很簡(jiǎn)單:
- 把方括號(hào)改成圓括號(hào)就可以了
打印出來是一個(gè)生成器:
<generator object <genexpr> at 0x7fa0b422feb0> 1 4 9這是一個(gè)生成器,它不會(huì)一次性生成100億個(gè)數(shù)字,只有調(diào)用next()的時(shí)候,它才會(huì)生成一個(gè)新的,返回給你。也就是說,同一個(gè)時(shí)間,只保存一個(gè)數(shù)字。
生成器的內(nèi)容請(qǐng)關(guān)注本公眾號(hào),下一期的終結(jié)者系列:生成器。
8 字典推導(dǎo)式
除了推導(dǎo)列表,生成器,還可以推導(dǎo)字典。
推導(dǎo)字典的方式和推導(dǎo)列表很相似,只不過:
1.使用大括號(hào)
2.使用鍵值對(duì)
推導(dǎo)一個(gè)包含數(shù)字和數(shù)字平方組成的字典,結(jié)果是這樣的:
{1: 1, 2: 4, 3: 9, ..., 100: 10000}代碼:
nums_dict = {n:n*n for n in range(1,101)} print(nums_dict)反過來,平方在前面,數(shù)字在后面:
nums_dict = {n*n:n for n in range(1,101)} print(nums_dict)給下面的字典按照分?jǐn)?shù)排序:
{'叔':59, '張三':87, 'FGA':78, '石石':100, '莫名':90}排序結(jié)果:
{'石石': 100, '莫名': 90, '張三': 87, 'FGA': 78, '叔': 59}代碼:
scores = {'叔':59, '張三':87, 'FGA':78, '石石':100, '莫名':90} sored_scores = {item[0]:item[1] for item in sorted(scores.items(), key=lambda item:item[1], reverse=True)} print(sored_scores)1.先把字典scores變成一個(gè)元組列表:「scores.items()」
2.用sorted函數(shù)給元組列表排序:「sorted(scores.items(), key=lambda item:item[1], reverse=True)」
3.排序過程用lambda指定使用元組的第二列排序:「key=lambda item:item[1]」。默認(rèn)是是第一列。
4.指定倒著排序,也就是分?jǐn)?shù)高的在前面:reverse=True
5.使用推導(dǎo)式,把排好序的元組列表,生成一個(gè)新的排好序的字典:「{item[0]:item[1] for item in … }」
9 集合推導(dǎo)式
推導(dǎo)集合的方式和列表是一樣的,區(qū)別在于:
1.使用大括號(hào),類似于推導(dǎo)字典,但它是單個(gè)元素,而不是鍵值對(duì)。
2.集合會(huì)自動(dòng)過濾掉重復(fù)的元素。
下面的名字列表,去掉前后空格后去掉重復(fù)的名字:
[ '叔', '張三', ' 麥?zhǔn)?', 'FGA ', '張小三', 'FGA', '石石',' 莫名','莫名' ]推導(dǎo)結(jié)果:
{'石石', 'FGA', '張小三', '莫名', '張三', '叔'}代碼:
names = [ '叔', '張三', ' 麥?zhǔn)?', 'FGA ', '張小三', 'FGA', '石石',' 莫名','莫名' ] new_names = {n.strip() for n in names} print(new_names)推薦閱讀
睡在我上鋪的室友用python,一個(gè)月掙了我一學(xué)期的生活費(fèi)
總結(jié)
以上是生活随笔為你收集整理的Python小知识:推导式用法大全,Comprehension的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【办公应用软件】万彩办公大师丨PDF页面
- 下一篇: 第一章 轻功盖世