Python 列表推導(dǎo) - PyTips 0x03

PyTips

項目地址:https://git.io/pytips

0x03 - Python 列表推導(dǎo)

0x02 中提到的 map/filter 方法可以通過簡化的語法快速構(gòu)建我們需要的列表(或其它可迭代對象),與它們功能相似的,Python 還提供列表推導(dǎo)(List Comprehension)的語法。最初學(xué) Python 的時候,我只是把這種語法當(dāng)做一種語法糖,可以用來快速構(gòu)建特定的列表,后來學(xué)習(xí) Haskell 的時候才知道這種形式叫做 List Comprehension(中文我好像沒有找到固定的翻譯,有翻譯成列表速構(gòu)、列表解析之類的,但意思上都是在定義列表結(jié)構(gòu)的時候按照一定的規(guī)則進行推導(dǎo),而不是窮舉所有元素)。

這種列表推導(dǎo)與數(shù)學(xué)里面集合的表達形式有些相似,例如$[0, 10)$之間偶數(shù)集合可以表示為:

$$\left{x\ |\ x \in N, x \lt 10, x\ mod\ 2\ ==\ 0\right}$$

翻譯成 Python 表達式為:

evens = [x for x in range(10) if x % 2 == 0]
print(evens)
[0, 2, 4, 6, 8]

這與filter效果一樣:

fevens = filter(lambda x: x % 2 == 0, range(10))
print(list(evens) == evens)
True

同樣,列表推導(dǎo)也可以實現(xiàn)map的功能:

squares = [x ** 2 for x in range(1, 6)]
print(squares)

msquares = map(lambda x: x ** 2, range(1, 6))
print(list(msquares) == squares)
[1, 4, 9, 16, 25]
True

相比之下,列表推導(dǎo)的語法更加直觀,因此更 Pythonic 的寫法是在可以用列表推導(dǎo)的時候盡量避免map/filter。

除了上面簡單的迭代、過濾推導(dǎo)之外,列表推導(dǎo)還支持嵌套結(jié)構(gòu):

cords = [(x, y) for x in range(3) for y in range(3) if x > 0]
print(cords)

# 相當(dāng)于
lcords = []
for x in range(3):
    for y in range(3):
        if x > 0:
            lcords.append((x, y))
            
print(lcords == cords)
[(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
True

字典與集合的推導(dǎo)

這樣一比較更加能夠突出列表推導(dǎo)的優(yōu)勢,但是當(dāng)嵌套的循環(huán)超過2層之后,列表推導(dǎo)語法的可讀性也會大大下降,所以當(dāng)循環(huán)嵌套層數(shù)增加時,還是建議用直接的語法。

Python 中除了列表(List)可以進行列表推導(dǎo)之外,字典(Dict)、集合(Set)同樣可以:

dns = {domain : ip
       for domain in ["github.com", "git.io"]
       for ip in ["23.22.145.36", "23.22.145.48"]}
print(dns)

names = {name for name in ["ana", "bob", "catty", "octocat"] if len(name) > 3}
print(names)
{'github.com': '23.22.145.48', 'git.io': '23.22.145.48'}
{'octocat', 'catty'}

生成器

0x01中提到的生成器(Generator),除了在函數(shù)中使用 yield 關(guān)鍵字之外還有另外一種隱藏方法,那就是對元組(Tuple)使用列表推導(dǎo):

squares = (x for x in range(10) if x % 2 == 0)
print(squares)

print(next(squares))
next(squares)

for i in squares:
    print(i)
<generator object <genexpr> at 0x1104fbba0>
0
4
6
8
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容