Pythonラーニング-ジェネレータ


リスト生成式により、リストを直接作成できます.ただし、メモリの制限を受けると、リストの容量は限られているに違いありません.また、100万個の要素を含むリストを作成すると、大きなストレージスペースを消費するだけでなく、前のいくつかの要素にアクセスするだけで、後ろのほとんどの要素が消費するスペースが無駄になります.
だから、リスト要素が何らかのアルゴリズムで推定できるなら、ループの過程で後続の要素を絶えず推定することができますか?これにより、listを完全に作成する必要がなくなり、大量のスペースを節約できます.Pythonでは、このように循環しながら計算するメカニズムをジェネレータ:generatorと呼ぶ
generatorを作成するには、さまざまな方法があります.1つ目の方法は簡単で、リスト生成式の[]を()に変更するだけでgeneratorが作成されます.
ls = [x*x for x in range(5)]
print(ls)
[0,1,4,9,16]
y = (m*m for m in range(5))
print(y,type(y))
 at 0x101380888> 

lsとyを作成する違いは、最外層の[]と()にすぎず、lsはlistであり、yはgeneratorである.
リストの各要素を直接印刷することができますが、generatorの各要素をどのように印刷しますか?
1つずつ印刷する場合はnext()関数でgeneratorの次の戻り値を取得できます.
print(next(y))
print(next(y))
print(next(y))
print(next(y))
print(next(y))
print(next(y))
0
1
4
9
16
Traceback (most recent call last):
   print(next(y))
StopIteration

generatorは、next(g)を呼び出すたびにgの次の要素の値を計算し、最後の要素まで計算し、より多くの要素がない場合にStopIterationのエラーを投げ出すアルゴリズムを保存します.
上記のnext(g)の呼び出しはあまりにも変態であり、generatorも反復可能なオブジェクトであるため、forループを使用するのが正しい.
y = (m*m for m in range(5))
for i in y:
    print(i)

0
1
4
9
16

したがって、generatorを作成すると、next()はほとんど呼び出されず、forループで反復され、StopIterationのエラーに関心を持つ必要はありません.
generatorはとても強いです.推定アルゴリズムが複雑で,リスト生成式のようなforループでは実現できない場合,関数で実現することも可能である.
例えば、有名なフィボラッチ数列(Fibonacci)は、最初の数と2番目の数を除いて、いずれの数も前の2つの数から加算することができます.
1, 1, 2, 3, 5, 8, 13, 21, 34, ...
フィポラチ数列はリスト生成式では書けませんが、関数で印刷するのは簡単です.
def fib(ma):
    n, a, b = 0, 0, 1
    while n  
  

,fib , , , generator.

generator 。 fib generator, print(b) yield b :

def fib(ma):
    n, a, b = 0, 0, 1
    while n  
  

generator 。 yield , , generator:

work = fib(6)
print(work)


ここで も しにくいのはgeneratorと の フローが なることです. は に され、return または の の に すると されます.generatorの となり、next()を び すたびに され、yield が され、 されると されたyield から が されます.
な を げてgeneratorを し、 1,3,5を に します.
def f1():
    print(111)
    yield 1
    print(222)
    yield 3
    print(333)
    yield 5

generatorを び す は、まずgeneratorオブジェクトを し、next() を して の り を します.
ret = f1()
print(next(ret))
print(next(ret))
print(next(ret))
print(next(ret))

1
222
3
333
5
Traceback (most recent call last):
    print(next(ret))
111
StopIteration

f 1は の ではなくgeneratorであり, にyieldに すると し, も を することがわかる.yieldを3 した 、yieldが できるようになったので、4 の び しnext(o)はエラーを します.
fibの に ると、ループ にyieldを び し けると、 し けます.もちろん、ループに を してループを します.そうしないと、 の が されます.
に、 をgeneratorに すると、next()で の り を するのではなく、forループを して します.
work = fib(6)
for i in work:
    print(i)

 
1
1
2
3
5
8

しかしforループでgeneratorを び すと、generatorのreturn の り が られないことがわかります. り を するには、StopIterationエラーを する があります.