Pythonラーニング-ジェネレータ
リスト生成式により、リストを直接作成できます.ただし、メモリの制限を受けると、リストの容量は限られているに違いありません.また、100万個の要素を含むリストを作成すると、大きなストレージスペースを消費するだけでなく、前のいくつかの要素にアクセスするだけで、後ろのほとんどの要素が消費するスペースが無駄になります.
だから、リスト要素が何らかのアルゴリズムで推定できるなら、ループの過程で後続の要素を絶えず推定することができますか?これにより、listを完全に作成する必要がなくなり、大量のスペースを節約できます.Pythonでは、このように循環しながら計算するメカニズムをジェネレータ:generatorと呼ぶ
generatorを作成するには、さまざまな方法があります.1つ目の方法は簡単で、リスト生成式の[]を()に変更するだけでgeneratorが作成されます.
lsとyを作成する違いは、最外層の[]と()にすぎず、lsはlistであり、yはgeneratorである.
リストの各要素を直接印刷することができますが、generatorの各要素をどのように印刷しますか?
1つずつ印刷する場合はnext()関数でgeneratorの次の戻り値を取得できます.
generatorは、next(g)を呼び出すたびにgの次の要素の値を計算し、最後の要素まで計算し、より多くの要素がない場合にStopIterationのエラーを投げ出すアルゴリズムを保存します.
上記のnext(g)の呼び出しはあまりにも変態であり、generatorも反復可能なオブジェクトであるため、forループを使用するのが正しい.
したがって、generatorを作成すると、next()はほとんど呼び出されず、forループで反復され、StopIterationのエラーに関心を持つ必要はありません.
generatorはとても強いです.推定アルゴリズムが複雑で,リスト生成式のようなforループでは実現できない場合,関数で実現することも可能である.
例えば、有名なフィボラッチ数列(Fibonacci)は、最初の数と2番目の数を除いて、いずれの数も前の2つの数から加算することができます.
1, 1, 2, 3, 5, 8, 13, 21, 34, ...
フィポラチ数列はリスト生成式では書けませんが、関数で印刷するのは簡単です.
だから、リスト要素が何らかのアルゴリズムで推定できるなら、ループの過程で後続の要素を絶えず推定することができますか?これにより、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エラーを する があります.