⚠️ 記事内に広告を含みます。

pythonでジェネレータ関数を使う(yield)

ジェネレータ関数

pythonでイテラブルなオブジェクトを作成するジェネレータ関数について

yieldを使ってジェネレータ関数を作成する

pythonのfor文ではイテラブルなりストやタプル、range()を使って変域を指定できます。
リストと同じようなものをジェネレーター関数といい、その作成にyieldを使います。

#ジェネレータ関数
def g():
    for a in range(3):
        yield a
    
print(g()) # generatorオブジェクトが返される
print(type(g())) # クラスがgeneratorになっている
---実行結果---
<generator object g at 0x0179C300>
<class 'generator'>

ジェネレータ関数g()をprintしても値はかえってこないです。
typeでみるとgeneratorとなっています。

# g()のaの値は0,1,2となってるはず?
for b in range(3):
    print(b) # 0,1,2と表示される
---実行結果---
0
1
2

ジェネレーター関数ではなく、単純にfor文で実行した結果は0,1,2がはいっています。

ジェネレーター関数から値を取り出す

def g():
    for a in range(3):
        yield a

## g()のaの値を取り出す方法 list(), tuple(), set()で取り出す
print(list(g())) # [0, 1, 2]が返される
print(tuple(g())) # (0, 1, 2)が返される
print(set(g())) # {0, 1, 2}が返される

# g()のaの値を取り出す方法 forループで取り出す
for c in g():   # g()をリストのようなイテラブルなオブジェクトとして利用
    print(c) # 0,1,2と表示される

# g()のaの値を取り出す方法 next()で取り出す
d = g()
print(next(d)) # 0が返される
print(next(d)) # 1が返される
print(next(d)) # 2が返される
#next関数は先頭から価を順番に取り出すもの。もう一回print(next(d)) をやると次の価は無いので、StopIterationエラーになる

実行結果

## g()のaの値を取り出す方法 list(), tuple(), set()で取り出す
[0, 1, 2]
(0, 1, 2)
{0, 1, 2}

# g()のaの値を取り出す方法 forループで取り出す
0
1
2

# g()のaの値を取り出す方法 next()で取り出す
0
1
2

for文で for c in g()というようにジェネレーター関数をイテラブルなオブジェクトとして利用できます。ジェネレーター関数は一つずつ値を返してくれます。ジェネレートした値をいれてlistとしてもtupleとしても取り出せます。

シンプルな例

def gene():
    yield "a"
    yield "b"
    yield "c"
    
for i in gene():
    print(i)

実行結果

a
b
c

ジェネレータ関数はforなどで取り出さないと呼び出しただけではreturnのように値を返さないので、メモリの節約になるそうです。

参考

https://qiita.com/keitakurita/items/5a31b902db6adfa45a70

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です