來源《python cookbook》第三版
問題:如果有序列,基於某些規則從中提取元素或者更改序列。
一、過濾數據
1.1 最簡單的是基於列表推導
mylist = [1, 4, 3, -5, 0, -11, -9]
[n for n in mylist if n>0]
缺陷在於如果列表非常大,會長生巨大的結果集佔用大量內存。若果對內存敏感,使用生成器表達式迭代元素。
pos = (n for n in mylist if n>0)
for x in pos:
print(x)
1.2 如果規則比較複雜,比如需要處理異常等,可以將代碼放入函數中,內建filter()函數
values = ['1', '2', '-3', '-', '4', 'N/A', '5']
def is_int(val):
try:
x = int(val)
return True
except ValueError:
return False
ivals = list(filter(is_int, values))
print(ivals)
# Outputs ['1', '2', '-3','4', '5']
二、過濾時添加轉換
>>>L = ['helLLO', 'World', 18, 'applE', None]
>>>[s.lower() for s in L if isinstance(s, str)]
# Outputs ['helllo', 'world', 18, 'apple', None]
# 2
>>>[s.lower() if isinstance(s, str) else s for s in L]
在for循環中,如果if條件通過則執行s.lower(),否則else執行s(不做變化)
三、另一種值得關注的過濾工具itertools.compress()
>>>addresses = [
'5412 N CLARK',
'5148 N CLARK',
'5800 E 58TH',
'2122 N CLARK'
'5645 N RAVENSWOOD',
'1060 W ADDISON',
'4801 N BROADWAY',
'1039 W GRANVILLE',
]
>>>counts = [ 0, 3, 10, 4,1,7, 6, 1]
提取counts大於5的地址
>>>from itertools import compress
>>>more5 = [n > 5 forn in counts]
>>>more5
[False, False, True, False, False, True, True, False]
>>>list(compress(addresses, more5))
['5800 E 58TH', '4801 NBROADWAY', '1039 W GRANVILLE']
>>>