序章

Pythonの組み込みfilter()関数を使用して、既存のイテレータ(listdictionaryなど)から新しいイテレータを作成し、私たちが提供する機能。 iterable は、「反復」できるPythonオブジェクトです。つまり、forループで使用できるように、アイテムを順番に返します。

filter()関数の基本的な構文は次のとおりです。

filter(function, iterable)

これにより、反復可能なフィルターオブジェクトが返されます。 list()のような関数を使用して、フィルターオブジェクトで返されるすべてのアイテムのリストを作成できます。

filter()関数は、リスト内包表記よりも効率的であることが多い値をフィルタリングする方法を提供します。特に、より大きなデータセットで作業を開始する場合はそうです。 たとえば、リスト内包表記は新しいリストを作成し、その処理の実行時間を増やします。 これは、リスト内包がその表現を完了した後、2つのリストがメモリにあることを意味します。 ただし、filter()は、元のリストへの参照、提供された関数、および元のリストのどこに移動するかのインデックスを保持する単純なオブジェクトを作成します。これにより、メモリの消費量が少なくなります。

このチュートリアルでは、filter()を使用する4つの異なる方法を確認します。2つの異なる反復可能な構造、lambda関数、および定義された関数なしです。

filter()を関数で使用する

filter()の最初の引数は、関数です。これを使用して、各アイテムを含めるか除外するかを決定します。 この関数は、2番目の引数として渡されたiterable内のすべての項目に対して一度呼び出され、Falseを返すたびに、値が削除されます。 この引数は関数であるため、特に式がそれほど複雑でない場合は、通常の関数を渡すか、lambda関数を使用できます。

lambdafilter()の構文は次のとおりです。

filter(lambda item: item[] expression, iterable)

次のようなリストを使用すると、lambda関数を、リストの各項目を評価する式に組み込むことができます。

creature_names = ['Sammy', 'Ashley', 'Jo', 'Olly', 'Jackie', 'Charlie']

このリストをフィルタリングして、母音で始まる水族館の生き物の名前を見つけるには、次のlambda関数を実行します。

print(list(filter(lambda x: x[0].lower() in 'aeiou', creature_names)))

ここでは、リスト内のアイテムをxとして宣言します。 次に、各文字列の最初の文字(または文字「ゼロ」)にアクセスするように式を設定します。つまり、x[0]です。 それぞれの名前の大文字と小文字を下げると、文字が式'aeiou'の文字列と一致するようになります。

最後に、反復可能なcreature_namesを渡します。 前のセクションと同様に、list()を結果に適用して、イテレータfilter()の戻り値からリストを作成します。

出力は次のようになります。

Output
['Ashley', 'Olly']

これと同じ結果は、次の関数を使用して実現できます。

creature_names = ['Sammy', 'Ashley', 'Jo', 'Olly', 'Jackie', 'Charlie']

def names_vowels(x):
  return x[0].lower() in 'aeiou'

filtered_names = filter(names_vowels, creature_names)

print(list(filtered_names))

関数names_vowelsは、creature_namesをフィルター処理するために実装する式を定義します。

この場合も、出力は次のようになります。

Output
['Ashley', 'Olly']

全体として、lambda関数は、通常の関数を使用する場合と同じ結果をfilter()で実現します。 データをフィルタリングするための式の複雑さが増すにつれて、通常の関数を定義する必要性が高まります。これにより、コードの可読性が向上する可能性があります。

Nonefilter()の使用

Nonefilter()の最初の引数として渡して、返されたイテレーターに、Pythonが「偽」と見なす値をフィルターで除外させることができます。 一般に、Pythonは、0の長さ(空のリストや空の文字列など)または0と数値的に同等のすべてのものを偽と見なします。したがって、「偽」という用語を使用します。

次の場合、リストをフィルタリングして、水族館の水槽番号のみを表示します。

aquarium_tanks = [11, False, 18, 21, "", 12, 34, 0, [], {}]

このコードには、 integers 、空のシーケンス、および booleanvalueを含むリストがあります。

filtered_tanks = filter(None, aquarium_tanks)

filter()関数をNoneとともに使用し、aquarium_tanksリストを反復可能として渡します。 最初の引数としてNoneを渡したので、リスト内の項目がfalseと見なされるかどうかを確認します。

print(list(filtered_tanks))

次に、filtered_tankslist()関数でラップして、印刷時にfiltered_tanksのリストを返すようにします。

ここでは、出力には整数のみが表示されます。 Falseと評価された、長さが0に相当するすべてのアイテムは、filter()によって削除されました。

Output
[11, 25, 18, 21, 12, 34]

list()を使用せずにfiltered_tanksを出力すると、<filter object at 0x7fafd5903240>のようなフィルターオブジェクトが返されます。 フィルタオブジェクトは反復可能であるため、for ループするか、list()を使用してリストに変換できます。これは、結果を確認します。

Noneでは、filter()を使用して、誤っていると見なされたアイテムをリストからすばやく削除しました。

辞書のリストでfilter()を使用する

より複雑なデータ構造がある場合でも、filter()を使用して各項目を評価できます。 たとえば、辞書のリストがある場合、リスト内の各項目(辞書の1つ)を反復処理するだけでなく、評価するために辞書内の各キーと値のペアを反復処理することもできます。すべてのデータ。

例として、水族館の各生き物のリストと、それぞれについてのさまざまな詳細があるとします。

aquarium_creatures = [
  {"name": "sammy", "species": "shark", "tank number": "11", "type": "fish"},
  {"name": "ashley", "species": "crab", "tank number": "25", "type": "shellfish"},
  {"name": "jo", "species": "guppy", "tank number": "18", "type": "fish"},
  {"name": "jackie", "species": "lobster", "tank number": "21", "type": "shellfish"},
  {"name": "charlie", "species": "clownfish", "tank number": "12", "type": "fish"},
  {"name": "olly", "species": "green turtle", "tank number": "34", "type": "turtle"}
]

このデータを、関数に指定した検索文字列でフィルタリングします。 filter()が各ディクショナリとディクショナリ内の各アイテムにアクセスできるようにするには、次のような入れ子関数を作成します。

def filter_set(aquarium_creatures, search_string):
	def iterator_func(x):
		for v in x.values():
			if search_string in v:
				return True
		return False
	return filter(iterator_func, aquarium_creatures)

aquarium_creaturessearch_stringをパラメーターとして受け取るfilter_set()関数を定義します。 filter_set()では、関数としてiterator_func()filter()に渡します。 filter_set()関数は、filter()の結果のイテレーターを返します。

iterator_func()は、xを引数として取ります。これは、リスト内の項目(つまり、単一の辞書)を表します。

次に、forループは、辞書の各キーと値のペアの値にアクセスし、条件ステートメントを使用して、search_stringが値を表すvにあるかどうかを確認します。

前の例のように、式がTrueと評価された場合、関数はアイテムをフィルターオブジェクトに追加します。 filter_set()機能が完了すると、これが返されます。 return Falseをループの外側に配置して、最初の辞書だけをチェックした後に戻るのではなく、各辞書のすべての項目をチェックするようにします。

辞書のリストと一致するものを検索する検索文字列を使用して、filter_set()を呼び出します。

filtered_records = filter_set(aquarium_creatures, "2")    

関数が完了すると、フィルターオブジェクトがfiltered_records変数に格納され、リストに変換されて次のように出力されます。

print(list(filtered_records))      

このプログラムから次の出力を受け取ります。

Output
[{'name': 'ashley', 'species': 'crab', 'tank number': '25', 'type': 'shellfish'}, {'name': 'jackie', 'species': 'lobster', 'tank number': '21', 'type': 'shellfish'}, {'name': 'charlie', 'species': 'clownfish', 'tank number': '12', 'type': 'fish'}]

検索文字列2を使用して辞書のリストをフィルタリングしました。 2のタンク番号を含む3つの辞書が返されていることがわかります。 独自の入れ子関数を使用することで、すべてのアイテムにアクセスし、検索文字列に対して各アイテムを効率的にチェックすることができました。

結論

このチュートリアルでは、Pythonでfilter()関数を使用するさまざまな方法を学びました。 これで、filter()を独自の関数、lambda関数、またはNoneと一緒に使用して、データ構造のさまざまな複雑さのアイテムをフィルタリングできます。

このチュートリアルでは、filter()の結果をリスト形式ですぐに出力しましたが、プログラムでは、返されたfilter()オブジェクトを使用して、データをさらに操作する可能性があります。

Pythonの詳細については、 Python3シリーズのコーディング方法とPythonトピックページをご覧ください。