[Python入門]ジェネレータの高度な話題Python入門(2/2 ページ)

» 2019年11月22日 05時00分 公開
[かわさきしんじDeep Insider編集部]
前のページへ 1|2       

yield from式

 前回紹介したyield式には、もう一つの形式がある。それがyield from式だ。これは「yield from 式」のような形で記述する。このとき「式」を評価した結果は反復可能オブジェクトまたはイテレータである必要がある。それが反復可能オブジェクトであれば、yield from式ではそれからイテレータを取り出して、そのイテレータから値を呼び出し側に順次返送できる機能だ。yield from式で使用するイテレータのことを「サブジェネレータ」と、yield from式で他のイテレータを利用することを「サブジェネレータへの委譲」呼ぶこともある。

 簡単な例を以下に示す。

def sample_geniter():
    yield from [1, 2, 3, 4]
    print('finished')

for num in sample_geniter():
    print(num)

print('hello')

yield from式の使用例

 ここではsample_geniterジェネレータ関数は、[0, 1, 2, 3]というリストに「処理を委譲」する。リストは反復可能オブジェクトなので、そのイテレータを使って、yield from式が実行されるたびにその要素を1つずつ返送してくれるということだ。

 実行結果を以下に示す。

実行結果 実行結果

 ここで重要なのは、yield from式は指定したサブジェネレータが持つ全ての値が返送されるまでは、構文上は処理が完了しないという点だ。そのため、上のコードでは全ての要素が列挙された後に、次の行が実行されて「finished」と表示され、yield式に到達することなくジェネレータイテレータが終了する。すると、StopIteration例外が発生するので、そこでfor文が終了する。

 上のコードをfor文を使わずにwhile文を使って書き直したものを以下に示す。これを実行してみると、「print('finished')」行が実行された後にStopIteration例外が発生しているのが分かるはずだ(実行結果は省略)。

def sample_geniter():
    yield from [0, 1, 2, 3]
    print('finished')

mygeniter = sample_geniter()
num = next(mygeniter)
while True:
    print(num)
    num = next(mygeniter)

上のコードをwhile文を使って書き直したもの

前のページへ 1|2       

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。