Python filter()內建函數用法詳解

2020-07-16 10:05:05
對序列資料進行過濾是個很常用的功能,Python 中提供了一個 filter() 內建函數,其可以很方便地實現對序列資料進行過濾。

filter() 函數的語法格式如下:

newIter = filter(function, iterable)

其中,各個引數的含義如下:
  • function:可傳遞一個用於判斷的函數,也可以將該引數設定為 None。
  • iterable:可疊代物件,包括列表、元組、字典、集合、字串等。
  • newIter:在 Python 2.x 中,該函數返回過濾後得到的新列表;而在 Python 3.x 中,該函數返回一個疊代器物件,可以用 list()、tuple() 等方法獲取過濾後得到的新序列。

正因為該函數是根據自定義的過濾函數進行過濾操作,所以支援更加靈活的過濾規格。

下面通過一個範例來演示 filter() 函數的用法。比如說,定義一個 list 變數,裡邊放置若干學生的成績資訊(包括語文、數學和英語)。要求使用 filter() 函數篩選出偏科的學生名單。

如何認定學生是否偏科呢?符合如下其中一條的學生,將被視為偏科:
  • 有 2 科成績在 80 分以上,有一科在 60 分以下。
  • 有 1 科成績在 90 分以上,另外 2 科成績都在 60 分以下。
  • 有 1 科成績在 90 分以上,但三科的平均分在 70 分以下。

實現程式碼如下:
scores = [ ("Emma", 89 , 90 , 59),
      ("Edith", 99 , 49 , 59),
      ("Sophia", 99 , 60 , 20),
      ("May", 40 , 94 , 59),
      ("Ashley", 89 , 90 , 59),
      ("Arny", 89 , 90, 69),
      ("Lucy", 79 , 90 , 59 ),
      ("Gloria", 85 , 90 , 59),
      ("Abby", 89 , 91 , 90)]

def handle_filter(a):
    s = sorted(a[1: ]) #對三科成績進行排序
    #有 2 科成績在 80 分以上,並且有 1 科在 60 分以下的
    if s[-2] > 80 and s[0] < 60 :
        return True
    #有 1 科成績在 90 分以上,另外 2 科成績都在 60 分以下
    if s[-1] > 90 and s[1] < 60 :
        return True
    if s[-2] > 80 and sum(s)/len(s) < 60:
        #有 1 科成績在 90 分以上, 且 3 科的平均分在 70 分以下
        return True
    return False

newIter = list(filter(handle_filter, scores))
print(newIter)
輸出結果為:

[('Emma', 89, 90, 59), ('Edith', 99, 49, 59), ('May', 40, 94, 59), ('Ashley', 89, 90, 59), ('Gloria', 85, 90, 59)]

此程式中,將自定義的 handle_filter() 函數作為 filter() 函數的第一個引數,用於過濾 scores 列表。由於在 Python 3.x 中 filter() 函數最終輸出的是疊代器物件,因此還需要借助 list() 內建函數,將其轉化為列表。