ジェネレーター
ジェネレーターはイテレーターの要素です。
イテレーターは反復処理で、リストのようなものを for loop で回していますが、
ジェネレーターは反復処理をしますがその際、一要素ずつ取り出してそれを生成します。
例を見てみます。
イテレーターの場合には以下の様になります。
l = ['Good morning', 'Good afternoon', 'Good night']
for i in l:
print(i)
Good morning Good afternoon Good night
ジェネレーターの場合も、同様に以下の様に出力されます。
def greeting():
yield 'Good morning'
yield 'Good afternoon'
yield 'Good night'
for g in greeting():
print(g)
Good morning Good afternoon Good night
イテレーターと同じように出力されます。
yield は産出するという意味です。ジェネレーターのキーワードになります。
ジェネレーターは yield の後の部分を一つ一つ generate(生成)していきます。
では、イテレーターとの違いの部分を見ていきます。
次に以下の様に書くと、同じことが起こります。
g = greeting() print(next(g)) print(next(g)) print(next(g))
次の様に出力されます。
Good morning Good afternoon Good night
そこで、間に print(‘@@@@@@@@@’) を入れてみます。出力されるでしょうか?
g = greeting()
print(next(g))
print('@@@@@@@@@')
print(next(g))
print(next(g))
Good morning
@@@@@@@@@
Good afternoon
Good night
出力されました。
for loop では一気に反復処理がなされますが、
ジェネレーターでは一つ一つ、一旦処理がループを抜けています。
最初の next(g) を実行した際 yield 以降を出力後、一旦ループを抜けます。
その後に @@@@@@@ を出力します。
その際、一つ目の next(g) を記憶しているので、また次の二つ目の next(g) を出力していきます。
run という文字を10回出力する、def counterというジェネレーターを追加します。
def counter(num = 10): for _ in range(num): yield 'run' def greeting(): yield 'Good morning' yield 'Good afternoon' yield 'Good night' g = greeting() c = counter() print(next(g)) #Good morning print(next(c)) #run print(next(c)) #run print(next(c)) #run print(next(c)) #run print(next(c)) #run print(next(g)) #Good afternoon print(next(c)) #run print(next(c)) #run print(next(c)) #run print(next(c)) #run print(next(c)) #run print(next(g)) #Good night
Good morning run run run run run Good afternoon run run run run run Good night
最初の print(next(g)) で Good morning を出力した後に、
print(next(c)) で run を5回出力し、
2回目の print(next(g)) では Good afternoon を出力しています。
つまり、1回目をの出力を記憶していて次の2回目に移っているわけですね。
このように、繰り返し処理の中で、他の処理を挟んだうえで、また処理を続けることが出来ます。
また、for i in range(10000000): のような for loop 回数の多い重たい処理が挟まれている場合、一気に処理をせず、小分けにして処理のタイミングをずらしたりできます。
def greeting(): yield 'Good morning' for i in range(10000000): print(i) yield 'Good afternoon' yield 'Good night'
最後の print(next(g)) #Good night の後に、更にprint(next(g)) を追加すると、もちろんエラーが返ってきます。
StopIteration という例外処理が返ってきます。
Good night
Traceback (most recent call last):
File "/home/ec2-user/environment/Myapp.py", line 30, in <module>
print(next(g))
StopIteration
コメント