python-進階教程-對列表中的元素進行篩選
0.摘要
本文主要介紹根據給定條件對列表中的元素進行篩序,剔除異常資料,並介紹列表推導式和生成表示式兩種方法。。
1.列表推導式(list comprehension)
mylist = [1, 2, 3, -4, -5, 6, 7, 8, 9]
positive_list = [n for n in mylist if n > 0 ]
print(positive_list)
#result:[1, 2, 3, 6, 7, 8, 9]
優點:簡單。列表推導式的實現非常簡單,在資料量不大的情況下很實用。
缺點:佔用記憶體大。由於列表推導式採用for迴圈一次性處理所有資料,當原始輸入非常大的情況下,需要佔用大量的記憶體空間。
2.生成器表示式
mylist = [1, 2, 3, -4, -5, 6, 7, 8, 9]
pos = (n for n in mylist if n > 0 )
print(pos)
for x in pos:
print(x)
其中的pos是我們構建的一個生成器,通過print()函式可以證實:<generator object <genexpr> at 0x000000DD6A9D0200>
相比於列表推導式,生成器表示式每次只處理一個數據,而不是處理整個資料結構,因此更加節約記憶體。
結論:處理少量資料用列表推導式,處理大量資料用生成器表示式
3.更復雜的篩選條件
有的時候篩選的標準並非如此簡單,甚至涉及到異常處理等細節,這個時候可以先將複雜的篩選條件寫入函式,該函式返回bool值,然後利用Python內建filter()函式進行處理。
values = ['1','-123', 'N/A', '-', '+369', 'hello'] def is_int(val): try: x = int(val) return True except ValueError: return False ivals = list(filter(is_int, values)) print(ivals) #result:['1', '-123', '+369']
利用int()轉換函式和異常處理函式實現的對int型資料的判斷;
filter()函式建立了一個迭代器,前面的list是將該迭代器轉換為list資料。
4.實用操作
在使用列表推導式和生成器表示式篩選資料的過程,還可以附帶著進行資料的處理工作。
mylist = [1, 4, -5, 10, -7, 2, 3, -1]
neg_clip = [n**2 if n > 0 else 0 for n in mylist]
print(neg_clip)
#result:[1, 16, 0, 100, 0, 4, 9, 0]
import math
pos_clip = [n if n < 0 else math.sqrt(n) for n in mylist]
print(pos_clip)
#result:[1.0, 2.0, -5, 3.1622776601683795, -7, 1.4142135623730951, 1.7320508075688772, -1]
另外,介紹一個篩選工具: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]
from itertools import compress
more5 = [ n > 5 for n in counts ]
print(more5)
#result:[False, False, True, False, False, True, True, False]
a = list(compress(addresses, more5))
print(a)
#result:['5800 E 58TH', '1060 W ADDISON', '4801 N BROADWAY']
這裡的more5將大於5的值替換為True,其餘替換為False。
itertools.compress(data, selectors):該函式會根據selectors中元素的bool值篩選data對應位置的元素,並返回一個迭代器。因此,需要對返回值取list才能檢視結果。
相比於filter()函式,itertools.compress()形式更簡單,不需要構建額外的函式。