python中的 3元表達式是對 if...else... 語句的一種簡寫~;這個在很多時候都非常有用,而且可以使代碼簡單且易于維護。
創(chuàng)新互聯(lián)建站是一家專注網(wǎng)站建設、網(wǎng)絡營銷策劃、微信小程序開發(fā)、電子商務建設、網(wǎng)絡推廣、移動互聯(lián)開發(fā)、研究、服務為一體的技術型公司。公司成立十余年以來,已經(jīng)為上千余家服務器租用各業(yè)的企業(yè)公司提供互聯(lián)網(wǎng)服務?,F(xiàn)在,服務的上千余家客戶與我們一路同行,見證我們的成長;未來,我們一起分享成功的喜悅。
x = 3
y = 4
if x > y:
res = x
else:
res = y
上述代碼若使用 3元表達式,if...else...語句可以簡寫成一行
x = 4
y = 3
res = x if x > y else y
上述例子中,3元表達式最左邊的 x 和最右邊的 y 可以寫成任意的表達式
x = 4
y = 3
res = 'aaa' if x > y else 'bbb'
列表解析(list comprehension),一般會配合 for 循環(huán),以比較優(yōu)雅的方式生成列表,大大減少代碼量,且增強了代碼的可讀性~
s = []
for i in 'hello':
s.append(i.upper())
print(s)
輸出結果:
['H', 'E', 'L', 'L', 'O']
上述代碼若使用列表解析,可使用如下代碼替換,輸出結果一致:
s = [i.upper() for i in 'hello']
print(s)
說明:for 循環(huán)得到的每一個元素返回給 for 前面的 i 變量,然后執(zhí)行 upper 函數(shù),將執(zhí)行結果以列表的形式返回~。相比于 for 循環(huán),列表解析的語法由 c語言實現(xiàn),性能會有所提升~
列表解析中,for 循環(huán)后面亦可添加 條件語句,篩選出滿足條件的元素:
lst = [1,2,60,67,34,78,98,70,89]
print([i for i in lst if i > 50])
輸出結果:
[60, 67, 78, 98, 70, 89]
總結一下列表解析的語法:
[expression for item1 in iterable1 if condition1
for item2 in iterable2 if condition2
.....
for itemN in iterableN if conditionN
]
絕大多數(shù)的情況,列表解析僅使用一層循環(huán),即:
[expression for item in iterable if condition]
上面已經(jīng)給出列表解析的語法,for 循環(huán)前面的 expression 可以是一個變量,也可以是一個表達式,看如下示例,列表中的×××(int)原樣取出,若是浮點類型(float),則進行四舍五入后取出:
a = [1,2,3.2,1.3,5.9]
res = [i if isinstance(i, int) else int(round(i)) for i in a]
res : [1, 2, 3, 1, 6]
這里 for 循環(huán)前的 expression 是一個三元表達式,判斷語句在三元表達式中實現(xiàn)~
for 循環(huán)前的 expression 也可以是一個 常量,例如要獲取一個固定長度的,且都是某個值的列表:
lst = [0 for i in range(10)] # 長度為10,全為0 的列表
lst : [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
列表解析多層 for 循環(huán)示例,讀取列表中每個單詞的字母,并生成一個新的列表:
lst = ['hello', 'kitty']
res = [l for word in lst for l in word]
res : ['h', 'e', 'l', 'l', 'o', 'k', 'i', 't', 't', 'y']
如上示例可能一下子難以理解,根據(jù)列表解析的語法:
[expression for item1 in iterable1 if condition1
for item2 in iterable2 if condition2
.....
for itemN in iterableN if conditionN
]
類似于
res=[]
for item1 in iterable1:
if condition1:
for item2 in iterable2:
if condition2:
......
for itemN in iterableN:
if conditionN:
res.append(expression)
如上示例使用 for 循環(huán)表示:
res = []
for word in lst:
for l in word:
res.append(l)
print(res)
輸出結果:
['h', 'e', 'l', 'l', 'o', 'k', 'i', 't', 't', 'y']
列表解析并沒有降低代碼的可讀性,且縮小了代碼量、提升了性能,但是若其中出現(xiàn)多層 for 循環(huán)嵌套,可能會降低代碼的可讀性,不易于理解~
列表解析會一次性生成所有的數(shù)據(jù)到內(nèi)存中,然后生成列表對象,這樣不適用于迭代大量的數(shù)據(jù)。 而生成器表達式正好解決了這個問題~
生成器表達式的語法與列表解析的語法類似,即外面的中括號 換成括號即可:
語法:
(expression for item1 in iterable1 if condition1
for item2 in iterable2 if condition2
.....
for itemN in iterableN if conditionN
)
示例:
>>> g = (i for i in range(100))
>>> g
at 0x00000288D8C9A308>
若使用生成器表達式,所有的數(shù)據(jù)不會一次性全部加載到內(nèi)存中,而是按照從前向后的順序,用到一個加載一個。當數(shù)據(jù)量比較大時,更節(jié)省內(nèi)存~
import time
start_time = time.time()
g = (i for i in range(100000000))
stop_time = time.time()
print('run time is %s' % (stop_time - start_time))
print(next(g))
print(next(g))
print(next(g))
輸出結果:
run time is 0.0 # 得到生成器 g 的用時~
0
1
2
同樣的數(shù)據(jù)量使用列表解析,會消耗相當長的時間,若是再加幾個0,程序可能就會卡?。?/p>
import time
start_time = time.time()
lst = [i for i in range(100000000)]
stop_time = time.time()
print('run time is %s' % (stop_time - start_time))
lst_iter = lst.__iter__()
print(next(lst_iter))
print(next(lst_iter))
print(next(lst_iter))
輸出結果:
run time is 5.407538890838623 # 生成列表的時長
0
1
2
當然生成器表達式也有缺點,由于生成器表達式返回的是一個生成器,所以若要迭代所有的元素,只能從前往后挨個迭代;而列表解析返回的是列表,可以根據(jù)索引立即返回指定位置的元素~
gen = (i for i in range(100))
# print(gen[10]) # 錯誤
lst = [i for i in range(100)]
print(lst[10]) # 沒有問題
.................^_^