Pythonのgeneratorとyieldとは?

こんにちは、のっくんです。

今日はPythonのyieldについて勉強していきましょう。

yieldを理解するには、returnとの違いを考えると良いです。

[toc]

returnの場合

1〜9の数値を返す関数を作ってみます。

def func_return():
    num_list = []
    for i in range(1,10):
        num_list.append(i)
    return num_list

li = func_return()
print(li)

returnの場合は、一括で全ての数値を返却します。この場合、戻り値は1~9の数値が入ったリストです。

yieldの場合

yieldはreturnとほぼ同じですが、yieldの場合は一旦停止して次回また再開します。

同じ機能を持つ関数をyieldを使って実装してみます。

def func_yield():
    for i in range(1, 10):
        yield i

gen = func_yield()

for x in gen:
    print(x)

例えば、上のコードの場合、1~9の値を順番に返却します。数値を生成して1つ返して、再度数値を生成して1つ返して、、、を9回繰り返し(イテレーション)します。

yieldが使われている関数はジェネレータ(generator)と呼ばれ、この関数の返り値は<generator object>になります。

yieldのメリット

yieldを使うメリットとして、メモリの消費を減らすことができます。

returnだと一括でまとめて値を返却するのでメモリを一気に消費しますが、yieldであれば少しずつ値を返却するのでメモリの消費を抑えられます。

上記の例だと9つの数値なのでメモリがあまりネックになりませんが、1GBのファイルを処理するコードではまとめて読み出すよりも1行ずつ処理した方が効率的です。

kerasの`ImageDataGenerator`のように画像を大量に処理する場合はyieldが内部で使われています。

一気にまとめて処理するのではなく、少しずつ処理することでメモリを効率的に使えるわけですね。

yiledを使うことで、よりPythonic(パイソニック)なコードが書けます。

人間も同じかもしれません。

大量に処理しようとするのではなく、何度も何度も繰り返すことが大事です。

おわり。

参考

http://ailaby.com/yield/#comment-19444

https://towardsdatascience.com/python-pro-tip-use-itertools-generators-and-generator-expressions-1b84911c978

ABOUTこの記事をかいた人

個人アプリ開発者。Python、Swift、Unityのことを発信します。月間2.5万PVブログ運営。 Twitter:@yamagablog