目錄
- 問題
- 解決方案
- 討論
問題
序列中包含一些數據,我們需要提取出其中的值或根據某些標準對序列做刪減。
解決方案
要篩選序列中的元素,通常最簡單的辦法是通過 列表推導式,例如:
mylist = [1, 4, -5, 10, -7, 2, 3, -1]print([n for n in mylist if n > 0])
print([m for m in mylist if m <= 0])
但是列表推導式存在著一些缺點,比如相對可讀性差,比如其會一次性生成整個列表,在生成非常大的列表時,會導致消耗大量內存。
相比之下,生成器表達式 可以更加有效地使用內存,因為其會逐個產生元素而不是一次性生成整個列表。
pos = (n for n in mylist if n > 0)
print(pos)
for x in pos:print(x)
有時候,如果篩選條件過于復雜,就不宜使用列表推導式以及生成器表達式。這時,我們可以選擇將篩選邏輯代碼放在單獨的函數中,然后使用內建的 filter()
函數處理。
values = ['1', '2', '-3', '-', '4', 'N/A', '5']def is_int(val):try:x = int(val)return Trueexcept ValueError:return Falseisvals = list(filter(is_int, values))
print(isvals)
filter()
創建了一個迭代器,而我們想要篩選得到列表中所有整數,且以列表的形式展示,所以加上 list()
。
討論
列表推導式以及生成器表達式通常是用來篩選數據的最簡單和最直接的方式。其功能強大,具備同時對數據進行轉換的能力:
mylist = [1, 4, -5, 10, -7, 2, 3, -1]import math
print([math.sqrt(n) for n in mylist if n > 0])
此外,列表推導式以及生成器表達式也可以實現同時對不滿足條件的字段做標注,比如標注出不滿足 >=0
的條件的值,其余值取平方根:
mylist = [1, 4, -5, 16, -7, -9, 25, 36]import math
print([math.sqrt(n) if n > 0 else -1 for n in mylist])
結果:
[1.0, 2.0, -1, 4.0, -1, -1, 5.0, 6.0]
此外,除了列表推導式以及生成器表達式,python 還提供一種篩選工具:itertools.compress()
,其接受一個可迭代對象以及一個布爾選擇器序列作為輸入。輸出時,會給出所有在相應的布爾選擇器中為 True
的可迭代對象元素。
address = ['5412 N CLARK','5149 N CLARK','5800 E 58TH','2122 N CLARK','5645 N RAVESWOOD','1060 W ADDISON','4901 N BROADWAY','1039 W GRANVILLE'
]counts = [0, 3, 10, 4, 1, 7, 6, 1]from itertools import compress
more5 = [n > 5 for n in counts]
print(list(compress(address, more5)))
['5800 E 58TH', '1060 W ADDISON', '4901 N BROADWAY']
同 filter()
函數一樣,compress()
同樣會返回一個迭代器,我們需要通過 list()
將其結果轉換為列表。