python 列表推導和生成器表達式的使用
序列
序列是指一組數據,按存放類型分為容器序列與扁平序列,按能否被修改分為不可變序列與可變序列。
容器序列與扁平序列
容器序列存放的是對象的引用,包括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'), ('white', '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)
運行結果是:
<generator object <genexpr> 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差不多,後面會講到。
Tips
本小節內容是我看《流暢的Python》第一遍時記錄的知識點:
- Python標準庫用C實現瞭豐富的序列類型。
- 列表推導,就是指
a = [x for x in something]
這種寫法。 - 生成器表達式用於生成列表外的其他類型的序列,它跟列表推導的區別僅僅在於方括號換成圓括號,如
b = tuple(x for x in something)
。 array.array('I', x for x in something)
,array構造方法的第一個參數指定瞭數組中數字的存儲方式。for tshirt in [c, s for c in colors for s in sizes]
,列表推導會一次性生成這個列表,存儲在內存中,占用資源。for tshirt in ('%s %s' for c in colors for s in sizes)
,生成器表達式隻在循環時逐個產出元素,避免額外的內存占用,省掉瞭運行for循環的開銷。
小結
本文首先介紹瞭序列的概念,然後演示瞭Python常規騷操作——列表推導,最後引出瞭生成器表達式這個看似復雜實則簡單的語法。列表是可變的,它有個不可變的孿生兄弟,元組。
參考資料:
《流暢的Python》
以上就是python 列表推導和生成器表達式的使用的詳細內容,更多關於python 列表推導和生成器表達式的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- python內置數據類型使用方法和繼承關系
- Python+OpenCV實現圖片及視頻中選定區域顏色識別
- Python中的元組(Tuple)操作實例詳解
- tuple在python中什麼意思 python中tuple的用法
- python中列表(list)和元組(tuple)的深入講解