ジェネレータの話
概要
そろそろジェネレータでも理解しようと思いました.
言語自体の詳細な仕様みたいなことはあまり勉強しないので正確な仕様はググったほうがいいです.
iterator
Pythonにおけるイテレータはだいたい反復可能なオブジェクトのことを指すはずです.
listやtupleやdictやそれらに似た色んなやつですね.
4. 組み込み型 — Python 3.6.5 ドキュメント
ものすごく噛み砕くと
__iter__()
と__next__()
を持っている__iter__()
でこいつはiterableなオブジェクトですよと宣言する__next__()
で次の要素にアクセスできる- for文は
__iter__()
,__next__()
を勝手に呼んでくれる
generator
オリジナルのiterableなオブジェクトを作りたいときgeneratorを使うようです.
__iter__()
と__next__()
を持ったクラスを作れば良いわけですがめんどくさいのでジェネレータで簡単に作ろうみたいな感じらしいです.yield
式を使います.
def
で関数を作るときにreturn
でなくyield
を使うことでその関数はジェネレータになり,1回値を生成したら中断して呼び出し元に制御が戻るみたいな動きをします.
適当に書いてみる
def myrange(start, stop, step): x = start while x < stop: yield x x += step
for i in myrange(0,5,1): print(i) """ 0 1 2 3 4 """
yield
なしも書いてみる.
class MyRange(object): def __init__(self, start, stop, step): self.start = start self.stop = stop self.step = step def __iter__(self): return self def __next__(self): if self.start >= self.stop: raise StopIteration() value = self.start self.start+=self.step return value
mr = MyRange(0,3,1) print(next(mr)) print(next(mr)) print(next(mr)) print(next(mr)) """ 0 1 2 --------------------------------------------------------------------------- StopIteration Traceback (most recent call last) """
yield
がすごく簡単なのが分かりました.
メリット
メモリの節約なんかに使うそうです.逆に言えば資源を気にしなくて良いときはあんまり使わないんですかね.
終わりに
ジェネレータ完全に理解した.