1. 程式人生 > 其它 >學習python -- 第022天 filter函式

學習python -- 第022天 filter函式

1、一般用法

filter()函式被用於過濾序列,它會過濾掉不符合條件的資料,符合條件的資料將會被留下,filter函式返回的結果是一個可迭代物件。

之所以稱它為高階語法,因為想要正確理解使用它並不容易,同時還要配合上lambda表示式。

filter的語法如下

filter(function, iterable)

function 是判斷函式,filter會遍歷iterable裡的每一個數據,用function進行判斷,如果符合條件,才會被留下。

iterable 是可迭代物件,如列表,元組,甚至集合都可以

下面是一個簡單的使用示例

from collections import Iterable

lst = [1, 2, 5, 6, 7]
res = filter(lambda x: x % 2 == 0, lst)
# res 是一個可迭代物件
print(isinstance(res, Iterable), type(res))
for item in res:
    print(item)

程式輸出結果

True <class 'filter'>
2
6

理解程式碼的關鍵有3點

1. filter 做了什麼

filter函式會遍歷列表lst, 用lambda表示式來判斷所遍歷到的資料是否符合要求

2. lambda 表示式做了什麼

列表lst中的資料會逐個傳給lambda表示式進行判斷,lambda表示式返回這些數是否為2的倍數,儘管沒有return語句,但lambda表示式預設返回 x % 2 == 0 的結果

3. filter函式的返回值是什麼

filter函式的返回值是一個可迭代物件,這一點很關鍵,這也是為什麼我說filter函式是高階語法的原因。

為什麼不返回列表?,如果返回的是列表,那麼在filter函式執行過程中,就必須對列表裡的每一個數據進行對2取模運算,這樣很浪費空間,因此filter在實現時採用了迭代器技術,將計算延遲到對filter函式返回結果進行遍歷時才進行。

怎麼驗證上面的說法呢,對程式碼稍加修改

from collections import Iterable

def func(x):
    print("接收引數" + str(x))
    return x%2 == 0

lst = [1, 2, 5, 6, 7]
res = filter(func, lst)
# res 是一個可迭代物件
print(isinstance(res, Iterable), type(res))

for item in res:
    print(item)

現在,我不使用lambda表示式對資料進行判斷,而是使用自由度更高的函式,在函式func中,我輸出接收到的引數,如果對lst資料中的過濾發生執行filter函式期間,那麼,在輸出res型別之前,就會執行函式func中的print語句,現在來看程式實際的執行結果

True <class 'filter'>
接收引數1
接收引數2
2
接收引數5
接收引數6
6
接收引數7

程式輸出結果表明,在執行filter函式時,並沒有呼叫func函式對lst中的資料進行過濾,而是在對res進行遍歷時才呼叫func函式進行過濾

2.結合偏函式,更加強大

單純的使用filter函式,就已經很強大了,結合了偏函式,則更加強大

from functools import partial

def even(x):
    return x%2 == 0

# 建立一個專門用來過濾保留偶數的函式
even_filter = partial(filter, even)
lst = [1, 2, 5, 6, 7]
res = even_filter(lst)

for item in res:
    print(item)

通過使用偏函式partial,我建立了一個專門用來過濾保留偶數的函式,其實最終還是呼叫執行了filter(even, lst),但使用even_filter時,我們可以不用去管函式even,在建立even_filter時,已經約定even作為filter的第一個引數來使用了。

認清現實,放棄幻想。 細節決定成敗,心態放好,認真學習與工作。