Featured image of post Pythonのジェネレータを理解する

Pythonのジェネレータを理解する

これはなに Link to this heading

Pythonのジェネレータとは何かを調べたメモ。

ジェネレータとは Link to this heading

Pythonにおけるジェネレータとは、遅延評価の性質を持つ特別なイテレータの一種である。

ジェネレータはイテレータであるため、__iter__()__next__()の2つのメソッドを持つ。また、遅延評価の性質を持つため、__next__()メソッドが呼ばれるまで次の要素を生成しない。__next__()メソッドが呼ばれてはじめて次の要素を生成する。

ジェネレータの定義方法 Link to this heading

ジェネレータの作成方法は下記の2つがある。

  1. ジェネレータ式の利用
  2. ジェネレータ関数の利用

ジェネレータ式とは Link to this heading

ジェネレータ式はジェネレータを返す記法である。 基本的な形は以下のようになる。リスト内法表記と似ている。

generator = (expression for item in iterable)

たとえば、下記コードは与えられたリストの各要素を2乗するジェネレータである。

numbers = [1, 2, 3, 4, 5]
squared = (x * x for x in numbers)

for number in squared:
    print(number)  # 1 4 9 16 25

ジェネレータ式に条件を設けることもできる。たとえば、上記のリストから偶数だけを取り出して2乗するジェネレータは次のようになる。

even_squared = (x * x for x in numbers if x % 2 == 0)

for number in even_squared:
    print(number)  # 4 16

ジェネレータ関数とは Link to this heading

ジェネレータ関数とは、ジェネレータを生成する関数である。通常の関数と同様にdefで定義するが、returnの代わりにyieldを使用する。yieldを使用すると、関数はジェネレータイテレータを返す。

基本的なジェネレータ関数の例を以下に示す。これは、0からlimitに指定した数までの整数を順に返す。

def count_up_to(limit):
    count = 0
    while count <= limit:
        yield count
        count += 1

counter = count_up_to(5)
for number in counter:
    print(number)  # 1 2 3 4 5

ジェネレータ関数は実行状態を保持する。そのため、次回の呼び出し時には前回の状態から続けて実行できる。また、ジェネレータ関数はジェネレータを返すため、要素を必要とするタイミングでのみ評価される。

ジェネレータの利点 Link to this heading

ジェネレータは__next__()メソッドが呼ばれるまで次の要素を生成しないため、メモリ効率が良い。また、一度にすべてのデータをメモリに保持する必要がないため、大量のデータを扱う際にも役立つ。

ジェネレータの利用シーン Link to this heading

  • 大規模なデータセット
  • 無限長のシーケンス
  • 計算量の大きいシーケンス

ジェネレータの注意点 Link to this heading

  • 一度next()で呼び出した値は破棄される。そのため、一度イテレートした後に再度イテレートする場合は、新たにジェネレータインスタンスを生成しなければならない
  • ジェネレータ関数はyield文を実行した時点で一時停止する。そのため、次の呼び出しあるいは関数の終了まで関数の実行は保持される

参考文献・URL Link to this heading

6. 式 (expression)'s image

6. 式 (expression)

この章では、Python の式における個々の要素の意味について解説します。 表記法に関する注意: この章と以降の章での拡張BNF (extended BNF) 表記は、字句解析規則ではなく、構文規則を記述するために用いられています。ある構文規則 (のある表現方法) が、以下の形式 で記述されていて、この構文特有の意味付け (semantics) が記述されていない場合、 name の形式をと...

docs.python.org
Licensed under CC BY-NC-SA 4.0
最終更新 9月 08, 2023
Hugo で構築されています。
テーマ StackJimmy によって設計されています。