ここがわかりやすい
– http://ailaby.com/yield/
– https://tokitsubaki.com/python-yield-statement/598/
目次
return
- 関数の処理を終了し、値を返す
yield
- 関数の処理を一時停止し、値を返す(次の行から再開)
- next(ジェネレーター) で次を取得する
yield は何に使う?
- メモリ使用量の少ないスクリプトが書ける
- 外側のループと、本来その内側に書いていた処理が別々にできる
例)
- 1GBの巨大なテキストファイルを読み込み、データを渡してくれる関数があった場合
- 受け渡し用のメモリが1GBという巨大なサイズになってしまう(returnの場合)
- これをyieldを使うと、少量単位(1行ずつ等)で都度読み込めるためメモリは少なくてすむ
用例
例1)ループ
def func():
a = 10
b = 20
c = a + b
yield c # ここで一旦停止
a = 100
b = 200
c = a + b
yield c # ここで一旦停止
a = 1000
b = 2000
c = a + b
yield c # ここで一旦停止
for x in func():
print (x)
#---- 結果 -----
# 30
# 300
# 3000
#---------------
例2)ループ以外
gen = func() # ジェネレータ
print (gen)
print (gen.__next__()) # 1 回目 # <- next(gen)でもよい
print (gen.__next__()) # 2 回目
print (gen.__next__()) # 3 回目
#---- 結果 -----
# <generator object func at 0x00000000145D1240>
# 30
# 300
# 3000
#-------------def func():
yield 'Hello'
yield 'Python'
gen = func()
>>>print(next(gen))
'Hello'
>>>print(next(gen))
'Python'ジェネレーター関数はそのままリストにできる
>>>list(gen)
['Hello', 'Python']yieldの使いどころ
- large.txtからyieldを使い1行だけ読み込む(ここをループ)
- 1行だけ読み込まれたlineに対し、処理を行う
- forで次の行を読み込みにいく….
# yield文を使ったファイルの読み込み
def read_line_gene(f_path):
with open(f_path) as f:
for line in f:
yield line
for line in read_line_gene('~/large.txt'):
print(line) ・・・処理yield from
- yield from文により、複数のジェネレータ関数を集約して1つのジェネレータ関数にできる
def odd_number_generator():
for n in range(10):
if n % 2 == 1:
yield n
print('-'*20) # ・・・区切りがわかりやすいように
def even_number_generator():
for n in range(10):
if n % 2 == 0:
yield n
def number_generator():
yield from odd_number_generator() # ・・・A
yield from even_number_generator() # ・・・B
for n in number_generator():
print(n)
ループの外側で処理が書ける★
- 本来、外側のループ(キー)を回し、その内側に処理を書くことが多い
- 両者を切り離すと、少し見やすいのでは。

ジェネレーター
Pythonのジェネレーターは、イテレータオブジェクトを作成するための一種の関数です。ジェネレーターは、通常の関数と似ていますが、return文の代わりにyield文を使用します。yield文は、関数の実行を一時停止し、値を返します。次に、関数が再度呼び出されたときに、停止した箇所から再開し、値を続けて返します。ジェネレーターは、ループでの使用や、大きなデータセットを扱うときなど、メモリ使用量を削減する場合に特に便利です。ジェネレーターを作成するには、ジェネレーター式や関数定義を使用できます。(ChatGPTより)
# ジェネレーターの作り方は簡単(丸かっこを使う)
code_list = ["0101", "0201", "0301", "0301", "0401", "0501", "0501", "0601", "0601"]
code_gene = (code for code in code_list)
code_gene(next) # 0101
code_gene(next) # 0201
...