python 列表推導和生成器表示式的使用

2022-10-03 09:45:10 字數 2543 閱讀 5357

序列是指一組資料,按存放型別分為容器序列與扁平序列,按能否被修改分為不可變序列與可變序列。

容器序列存放的是物件的引用,包括list、tuple、collections.deque。

扁平序列存放的是物件的值,包括str、bytes、bytearray、memoryview和array.array。

扁平序列的值是字元、位元組和數值這種基礎型別。

不可變序列,包括tuple、str、bytes。

可變序列,包括list、bytearray、array.array、collection.deque、memoryview。

下圖左邊是父類,右邊是子類,可以看出可變序列是從不可變序列繼承來的,擴充套件了可變方法:

python語言魅力在於簡潔,這能從最常見的建立列表體現出來,比如我們想把字串"abc"轉換成新列表["a", "b", "c"],常規寫法:

symbols = "abc"

codes =

for symbol in symbols:

codes.append(symbol)

print(codes) # ["a", "b", "c"]

用到了for迴圈和列表append方法。實際上可以不用append方法,直接:

symbols = "abc"

codes = [symbol for symbol in symbols]

這叫做列表推導,是更加pythonic的寫法。

無論是編寫效率還是可閱讀性,列表推導都更勝一籌,可以說是構建列表的快捷方式。但是不能濫用,通用原則是,如果列表推導的**超過了兩行,就要考慮用append了。這不是規定,完全可以憑藉自我喜好來選擇。

笛卡爾積是指多個序列中元素所有組合,我們用列表推導來實現笛卡爾積:

colors = ["black", "white"]

sizes = ["s", "m", "l"]

tshirts = [(color, size) for color in colors for size in sizes]

一行**搞定!life is short,use python,list comprehension is wonderful,amazing。

注意這行**有兩個for迴圈,等價於:

for color in colors:

for size in sizes:

執行結果是:

[('black', 's'), ('black', 'm'), ('black', 'l'), ('white', 's'), ('white', 'm'), ('white', 'l')]

如果換一下順序:

[(color, size) for color程式設計客棧 in colors for size in sizes]

等價於:

for size in sizes:

for color in colors:

執行結果是不同的,觀察第2個元素:

[('black', 's'), ('white', 's'), ('black', 'm'), ('w', 'm'), ('black', 'l'), ('white', 'l')]

一般接觸到生成器時,都要講yield關鍵字,看似有點複雜,然而卻很簡單,生成器就像列表推導一樣,只不過是用來生成其他型別序列的,比如元組:

symbols = "abc"

codes = (symbol for symbol in symbols)

它的語法非常簡單,把列表推導的中括號換成小括號(),就可以了。

語法相似,本質上卻有很大區別,我們試著用生成器表示式來實現笛卡爾積,看看會有什麼變化:

colors = ["black", "white"]

sizes = ["s", "m", "l"]

tshirts = ((color, size) for color in colors for size in sizes)

執行結果是:

at 0x000001fd57d2db30>

generator object,結果是乙個生成器物件。因為生成器表示式在每次迭代時才會逐個產出元素,所以這裡的結果並不是已經建立好的元組。列表推導才會一次性產生新列表所有元素。

通過迭代把生成器表示式結果輸出:

for tshirt in tshirts:

print(tshirt)

('black', 's')

('white', 's')

('程式設計客棧black', 'm')

('white', 'm')

('black', 'l')

('white', 'l')

生成器表示式可以提公升程式效能,比如要計算兩個各有1000個元素的列表的笛卡爾積,生成器表示式可以幫忙省掉執行for迴圈的開銷,即乙個包含100萬個元素的列表。

yield作用和return差不多,後面會講到。

本小節內容是我看《流暢的python》第一遍時記錄的知識點:

本文首先介紹了序列的概念,然後演示了python常規騷操作——列表推導,最後引出了生成器表示式這個看似複雜實則簡單的語法。列表是可變的,它有個不可變的孿生兄弟,元組。

《流暢的python》

生成器,生成器推導式和列表推導式

python社群,大部分生成器和迭代器是一種 生成器的本質是迭代器 唯一區別 生成器是我們自己用python 構建的資料結構 迭代器都是提供的,或者轉化得來的 生成器函式 生成器表示式 python提供的 yield 乙個next 對應乙個yield yield和下乙個yield中間有 的話只執行乙...

python 列表推導和生成器表示式

一 列表推導式 通常原則只用來建立新列表,並盡量保持簡短,如果列表 超過了兩行,就要考慮是不是得用for迴圈重寫了 例子1 1 建立新列表 new list i for i in range 10 print new list 執行結果 f virtualenvironment venv scrip...

生成器及列表推導式

迭代器 內部含有 iter next 方法的物件 可迭代物件不能取值,因為內部沒有 next 的方法 迭代器的優點 1 節省記憶體 2 惰性機制 3 單向 不可逆 如何判斷可迭代物件 迭代器 1 iter in dir obj 2 引用乙個模組 from collections import ite...