Pythonのジェネレータ内包表記(generator comprehension)の使い方について解説します。
Contents
ジェネレータ内包表記(generator comprehension)
Pythonにおけるジェネレータ内包表記(generator comprehension)は、既存リスト等のイテラブルなオブジェクトから、ジェネレータのオブジェクトを作成する際にシンプルに記載するための定義方法です。なお、ジェネレータについては「ジェネレータ関数とジェネレータの基本」を参考にしてください。
この記事では、ジェネレータ内包表記の基本的な使い方について紹介します。
ジェネレータ内包表記の使い方
ジェネレータ内包表記の構文は以下になります。
(式 for 仮変数 in イテラブルなオブジェクト if 条件)
上記の意味合いとしては、イテラブルなオブジェクトから要素を順番に仮変数に取得し、条件に一致するものに対して式を適用した値を返却するようなジェネレータオブジェクトを作るということになります。
なお、(
で始まるのでタプル内包表記のように思われるかもしれませんが、タプル内包表記というものはありません。タプルにする場合は、変換するという作業が必要です。
ジェネレータ内包表記を使う場合
ジェネレータ内包表記を使用するには以下のようにします。
gen = (i for i in range(10) if i % 2 == 0) print(type(gen)) for i in gen: print(i)
【実行結果】 <class 'generator'> 0 2 4 6 8
上記例では、2
で割り切れる数値を生成するジェネレータを作成しています。gen
は、ジェネレータのオブジェクト(<class 'generator'>
)となります。
ジェネレータオブジェクトは、イテレータの一種のため例のようにfor
文で繰り返しに使用したり、next(gen)
のように順に値を取り出して使用したりできます。
タプルやリストに変換したい場合
ジェネレータ内包表記では、ジェネレータのオブジェクトを生成します。タプルやリストに変換したい場合は、以下のように変換することが可能です。
# ジェネレータからタプルに変換 gen = (i for i in range(10) if i % 2 == 0) tpl_tmp = tuple(gen) print(type(tpl_tmp), tpl_tmp) # ジェネレータからリストに変換 gen = (i for i in range(10) if i % 2 == 0) list_tmp = list(gen) print(type(list_tmp), list_tmp)
【実行結果】 <class 'tuple'> (0, 2, 4, 6, 8) <class 'list'> [0, 2, 4, 6, 8]
ジェネレータはメモリを節約しながら無限シーケンスを扱えるため、タプルやリストに変換する際は、その利点が失われることを考慮し、変換の必要性を十分検討しましょう。
ジェネレータ内包表記を使用しないで記載する場合
ジェネレータ内包表記は、ジェネレータ関数として書き換えることが可能です。
# ジェネレータ関数で定義 def generate_num(): for g in range(10): if g % 2 == 0: yield g gen = generate_num() print(type(gen)) for i in gen: print(i)
ジェネレータ内包表記の特徴と注意点
ジェネレータ内包表記は、処理をシンプルに記述できる点が特徴です。また、ジェネレータ内包表記は、Python内部で最適化されているため、一般的に実行速度も速くなります。特に、大きなデータセットやメモリ効率が重要な場合に積極的に採用するのが良いでしょう。ただし、処理速度は状況によって異なり、必ずしも常に早いとは限らないため、その点には注意が必要です。
また、ジェネレータ内包表記がコードを複雑にする場合は、使用を慎重に検討してください。特にチーム開発では、ソースコードの可読性が重要ですので、シンプルさと可読性のバランスを保つことが重要です。
まとめ
Pythonのジェネレータ内包表記(generator comprehension)の使い方について解説しました。
ジェネレータ内包表記は、イテラブルなオブジェクトからジェネレータのオブジェクトを作成する際にシンプルに記載するための定義方法です。この記事では、ジェネレータ内包表記の基本的な使い方や特徴と注意点を紹介しました。
Pythonにおける内包表記は他にも「リスト内包表記」「辞書内包表記」「集合内包表記」といったものがあります。内包表記については「内包表記(まとめ)」を参考にしてください。
上記で紹介しているソースコードについてはgithubにて公開しています。参考にしていただければと思います。