1. 程式人生 > >python-進階教程-對列表中的元素進行篩選

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()形式更簡單,不需要構建額外的函式。