関数

【Python】filter関数の使い方の基本 ~条件を満たす要素を抽出~

【Python】filter関数の使い方の基本 ~条件を満たす要素を抽出~
naoki-hn

Python の組み込み関数である filter 関数を使って条件を満たす要素を抽出する方法を解説します。

filter 関数で条件を満たす要素を抽出する

filter 関数は、関数と処理対象のイテラブルを受け取って、特定の条件を満たす要素を抽出する Python の組み込み関数です。

このように引数に関数を受け取る関数は高階関数と言います。for 文でも同じ処理ができますが、繰り返し処理を書かずともシンプルに記載できる点がメリットです。

filter 関数は、関数型プログラミング言語においてよく使用される代表的な関数です。Python はマルチパラダイムの言語と言われているため、厳密ではありませんが関数型プログラミングのスタイルもサポートしており、filter 関数が組み込み関数として利用できます。

この記事では、リストの要素を関数で評価してフィルタする例を用いて、filter 関数の使い方の基本を紹介します。

filter 関数と同様に関数型プログラミングに関連のある関数として map 関数、reduce 関数、partial 関数があります。以下ページも参考にしてください。

filter 関数の基本的な使い方

filter 関数の基本的な構文は以下の通りです。

result = filter(関数, イテラブル)

filter 関数は、イテラブル の各要素に 関数 を適用し、条件を満たす要素を抽出(フィルタ)した結果のイテレータを返却します。フィルタされた結果は next を用いることで順に取り出したり、for 文で繰り返し取り出して使用したりすることができます。

後述の例でも紹介しますが、list(filter(関数, イテラブル)) のようにすることでリストに変換して取得することも可能です。ただし、大きなサイズのフィルタ結果の場合は、リストに変換しない方が効率的である場合もあるので注意して使用してください。

filter 関数は条件を満たす要素の抽出が目的のため、引数に指定する関数 は「与えられた要素に対して真偽を評価できる値を返却する必要がある」点に注意してください。

【真偽を評価できる値 (truthy / falsy)】

上記において「真偽を評価できる値」とは、if 文の条件式として使える値のことです。Python では、値を True / False として評価する仕組みがあり、None0、空文字列 ""、空のリスト [] などは False(falsy) として扱われ、それ以外は True(truthy) として扱われます。

イテレータの基本は以下を参考にしてください。

イテレータ(iterator)の基本

基本的な使い方

filter 関数の基本的な使い方を以下の例を用いて見ていきましょう。

def is_even(num):
    """数値が偶数か判定する"""
    return num % 2 == 0


if __name__ == "__main__":
    tmp_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

    # filter関数を適用し、イテレータを取得
    result = filter(is_even, tmp_list)
    print(result, "\n")

    # nextで1要素ずつ結果データを取得
    print(next(result))
    print(next(result))
    print(next(result))
    print(next(result))
    print(next(result))
【実行結果】
<filter object at 0x000001FA10FB45E0> 

2
4
6
8
10

例では、受け取った数値が偶数かどうかを判定する is_even 関数が定義されており、tmp_list の各要素が偶数かどうかをフィルタしています。

filter 関数を呼び出している部分では「filter(is_even, tmp_list)」というように関数と処理対象のリストを渡しています。ここで、関数を渡す際には () をつけないことがポイントです。関数は is_even(2) のように () で引数を指定すると関数を実行することを意味しますが () がない場合は関数そのものを表します。filter 関数は、受け取った is_even という関数を内部で実行しているわけです。

また、filter 関数は条件を満たす要素を抽出することが目的であるため、フィルタの判定ができるように is_even 関数は True / False を返却しています。

filter 関数の返却値は「filter object」となっていますが、これはイテレータの一種です。next 関数を使用することで次の要素を順番に取得することができます。この例では、tmp_list の要素で偶数である数値が順に取得されていることが分かります。

注意点

例で next(result) を再度実行すると StopIteration 例外が発生します。これは、イテレータがもう要素を持たない場合に発生する例外です。StopIterationfor の繰り返しの終了判定に使用されています。

【実行結果】
Traceback (most recent call last):
...(省略)...
StopIteration

リストやタプルで取得する方法

filter 関数の返却値はイテレータであるため、以下のように listtuple に変換することができます。

def is_even(num):
    """数値が偶数か判定する"""
    return num % 2 == 0


if __name__ == "__main__":
    tmp_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

    # filter関数を適用し、リストで取得
    result = list(filter(is_even, tmp_list))
    print(result)

    # filter関数を適用し、タプルで取得
    result = tuple(filter(is_even, tmp_list))
    print(result)
【実行結果】
[2, 4, 6, 8, 10]
(2, 4, 6, 8, 10)

関数に None を指定する方法

filter 関数では、関数 として設定する引数に None を指定することが可能です。その場合は、フィルタ対象の要素が truthy である要素のみ抽出します。truthy とは、if 文で True と判定される値のことです。(None0、空文字列 ""、空のリスト [] などは False 扱いとなり抽出されません。)

以下の例で確認してみましょう。

tmp_list = [0, 1, "", "Hello", [], [1, 2, 3], None, True, False]

# None を指定すると要素の truthy/falsy で判定される
result = list(filter(None, tmp_list))
print(result)
【実行結果】
[1, 'Hello', [1, 2, 3], True]

例のように、関数として None を指定することで truthy となる値のみがフィルタできることが分かります。欠損値や空データをお手軽に取り除く方法として使用できます。

注意点

filter(None, ...) は、便利な方法ですが、0False も除外されるため、想定外の結果にならないか十分に注意して使用してください。

ラムダ関数(無名関数)と組み合わせる方法

filter 関数では、ラムダ関数(無名関数)と組み合わせることで、より手軽に条件を満たす要素を抽出することができます。ラムダ関数は、関数定義を def で定義することなく、その場で作れるもので関数型プログラミングでは非常によく使われる概念です。

is_even 関数をラムダ関数にして filter 関数で使う例を見てみましょう。

tmp_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# filter関数を適用し、リストで取得
result = list(filter(lambda x: x % 2 == 0, tmp_list))
print(result)

# filter関数を適用し、タプルで取得
result = tuple(filter(lambda x: x % 2 == 0, tmp_list))
print(result)
【実行結果】
[2, 4, 6, 8, 10]
(2, 4, 6, 8, 10)

これまでの例で is_even と関数を指定していた部分に「lambda x: x % 2 == 0」というラムダ関数を指定しています。結果は is_even 関数を使った場合と同じです。

ラムダ関数は無名関数ともいわれる通り、関数名はありませんが、そのものが関数として扱われるため、filter 関数に渡すことでリストの各要素に関数を適用してフィルタした結果を取得できます。

ラムダ関数の基本については以下を参考にしてください。

ラムダ(lambda)関数:無名関数の使い方

まとめ

Python の組み込み関数である filter 関数を使って条件を満たす要素を抽出する方法を解説しました。

filter 関数は、関数と処理対象のイテラブルを受け取って、特定の条件を満たす要素を抽出する Python の組み込み関数です。filter 関数は他の関数型プログラミング言語でもよく使用される代表的な関数で Python でも使用できます。

filter 関数は for 文を用いなくてもシンプルに関数で条件判定するフィルタ処理ができることが特徴です。

非常に強力な機能ではありますが、filter 関数の適用が常に最適な選択というわけではありません。場合によっては for 文で書いた方が可読性が上がる可能性もあります。目的に応じて適切に方法を選択できるよう filter 関数の使い方を理解しておくようにしましょう。

ソースコード

上記で紹介しているソースコードについては GitHub にて公開しています。参考にしていただければと思います。

あわせて読みたい
【Python Tech】プログラミングガイド
【Python Tech】プログラミングガイド

ABOUT ME
ホッシー
ホッシー
システムエンジニア
はじめまして。当サイトをご覧いただきありがとうございます。 私は製造業のメーカーで、DX推進や業務システムの設計・開発・導入を担当しているシステムエンジニアです。これまでに転職も経験しており、以前は大手電機メーカーでシステム開発に携わっていました。

プログラミング言語はこれまでC、C++、JAVA等を扱ってきましたが、最近では特に機械学習等の分析でも注目されているPythonについてとても興味をもって取り組んでいます。これまでの経験をもとに、Pythonに興味を持つ方のお役に立てるような情報を発信していきたいと思います。どうぞよろしくお願いいたします。

※キャラクターデザイン:ゼイルン様
記事URLをコピーしました