[PY3]——過濾資料——列表推導、filter()、itertools.compress()

Jelly_lyj發表於2017-03-18

問題

你有一個資料序列,想利用一些規則從中提取出需要的值或者是縮短序列

解決方案

最簡單的過濾資料的方法,就是使用列表推導。

使用列表推導的一個潛在缺陷就是如果輸入非常大的時候會產生一個非常大的結果集,對記憶體敏感時可以考慮使用生成器表示式迭代產生過濾元素

在過濾規則比較複雜不便於用簡單的列表推導就寫出來的情況下,這時可以考慮寫成將規則寫成一個函式,然後使用內建的 filter() 函式

還有過濾工具 itertools.compress() 

 

列表推導

lst=[1,4,-5,10,-7,2,3,-1]
print([n for n in lst if n>0])
 [1, 4, 10, 2, 3]

#若考慮記憶體佔用情況,則:
result=[n for n in lst if n>0]
for x in result:
    print(x)
 1
 4
 10
 2
 3

 

filter(函式,序列)

filter()接收一個函式和一個序列。

filter()會把傳入的函式依次作用於每個元素,然後根據返回值是True還是False決定保留還是丟棄該元素。

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)
     ['1', '2', '-3', '4', '5']

# 用filter()刪除1~100的素數

 

itertools.compress(data,selectors)

compress 可用於對資料進行篩選,當 selectors 的某個元素為 true 時,則保留 data 對應位置的元素,否則去除

from itertools import compress
print(list(compress("ABCDEF",[1,0,1,0,1,1])))
    ['A', 'C', 'E', 'F']
print(list(compress("ABCDEF",[True,False,True,False,True,True])))
    ['A', 'C', 'E', 'F']

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]
print(list(compress(addresses,[n>5 for n in counts])))
     ['5800 E 58TH', '1060 W ADDISON', '4801 N BROADWAY']

 

過濾資料時轉換資料

import math
print([math.sqrt(n) for n in lst if n>0])
    [1.0, 2.0, 3.1622776601683795, 1.4142135623730951, 1.7320508075688772]

 

過濾資料時替換資料

print([n if n>0 else 0 for n in lst])
    [1, 4, 0, 10, 0, 2, 3, 0]
print([n if n<0 else '-' for n in lst])
    ['-', '-', -5, '-', -7, '-', '-', -1]

 

參考文章

filter-廖雪峰的網站

itertools模組介紹-極客學院

相關文章