0
2

[Python]ジェネレータ

Posted at

ジェネレータ

ジェネレータ(generator)は、Pythonでイテレータ(iterator)を生成する関数です。通常の関数と異なる点は、関数が呼び出されるたびに return キーワードで値を返して終了する代わりに、yield キーワードを使用して値を返し、一時的に関数の状態を保持し、次に呼び出されたときに続きから実行できる点です。

ジェネレータ関数は呼び出されるとジェネレータオブジェクトを返し、このオブジェクトは iterable インターフェースを実装し、next() 関数を使用して値を順次取得することができます。ジェネレータはメモリを効率的に使用し、大容量のデータや無限シーケンスを扱うのに役立ちます。

例:

def countdown(n):
    while n > 0:
        yield n
        n -= 1

# ジェネレータオブジェクトの作成
gen = countdown(5)

# 値を順次取得する
print(next(gen))  # 5
print(next(gen))  # 4
print(next(gen))  # 3
print(next(gen))  # 2
print(next(gen))  # 1

上記の例では、countdown 関数はジェネレータ関数であり、yield を使用して値を返し、関数の状態を保持します。next() 関数を呼び出して値を1つずつ取得できます。最後の値を取得すると StopIteration 例外が発生し、これ以上値がないことを通知します。

ジェネレータはイテレータを使用するすべての場面で使用でき、リストやタプルなどの他のコレクションタイプと同様に for ループを使用して処理することができます。


yield

yield キーワードは、主にジェネレータ(generator)関数内で使用される特別なキーワードです。このキーワードを使用すると、関数は呼び出されるたびに値を返し、その後も関数の実行状態を一時停止し、次に呼び出されたときにその続きから実行を再開することができます。

通常、関数が値を返すと、その時点で関数は終了し、次の呼び出し時には新たに実行されます。しかし、yield を使うと、関数は現在の実行状態を保持し、その状態で値を呼び出し元に返した後も、次の呼び出し時までその状態を覚えています。

簡単な例を使って yield の動作を説明します:

def simple_generator():
    yield 1
    yield 2
    yield 3

# ジェネレータオブジェクトを作成
gen = simple_generator()

# 値を順に取得する
print(next(gen))  # 1
print(next(gen))  # 2
print(next(gen))  # 3
print(next(gen))  # StopIteration 例外が発生

上記の例では、simple_generator 関数がジェネレータ関数であり、各 yield 文がジェネレータオブジェクトが呼び出された時に値を返します。next() 関数を使って値を一つずつ取得し、すべての値を返した後に StopIteration 例外が発生して、これ以上の値がないことを示します。

yield は値を単に返すだけでなく、関数の実行状態を保持する点が重要です。そのため、ジェネレータ関数はイテラブル(iterable)オブジェクトを生成し、そのオブジェクトは for ループや他の反復処理で使用することができます。


next()

next() 関数は、Pythonでイテレータ(iterator)やジェネレータ(generator)を操作するための関数です。主に以下のような場面で使用されます。

  1. イテレータの値を取得する:
    イテレータやジェネレータは、next() 関数を使って次の要素を順に取得できます。例えば、以下のように使用します。

    my_iter = iter([1, 2, 3])
    print(next(my_iter))  # 1
    print(next(my_iter))  # 2
    print(next(my_iter))  # 3
    

    イテレータが最後の要素を返した後にさらに next() を呼び出すと、StopIteration エラーが発生します。

  2. ジェネレータの値を取得する:
    ジェネレータ関数から生成されたジェネレータオブジェクトでも同様に使用できます。

    def my_generator():
        yield 1
        yield 2
        yield 3
    
    gen = my_generator()
    print(next(gen))  # 1
    print(next(gen))  # 2
    print(next(gen))  # 3
    

    同様に、最後の要素を返した後に next() を呼び出すと StopIteration エラーが発生します。

  3. デフォルト値を指定する:
    next() 関数の第二引数としてデフォルト値を指定することができます。これは、イテレータが最後に達したときに StopIteration エラーを発生させずに、代わりにデフォルト値を返すために使用されます。

    my_iter = iter([1, 2])
    print(next(my_iter, 0))  # 1
    print(next(my_iter, 0))  # 2
    print(next(my_iter, 0))  # 0 (デフォルト値)
    

    上記の例では、イテレータが最後の要素を返した後に next() を呼び出すと、デフォルト値 0 が返されます。

next() 関数は反復処理を行う際に非常に便利であり、特に動的なデータセットや無限のシーケンスを扱う際に役立ちます。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2