黒猿の家:pythonジェネレータ

2141 ワード

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

#    
#    ,      ,              
#    ,        
#   ,    
>>> g = (x * x for x in range(10))
>>> g
 at 0x1022ef630>

Lとgの違いは、最外層の[]と()のみであり、Lはlistであり、gはgeneratorである.リストの各要素を直接印刷することができますが、generatorの各要素をどのように印刷しますか?1つずつ印刷する場合はnext()関数でgeneratorの次の戻り値を取得できます.
>>> g.__next__()
0
>>> g.__next__()
1
>>> g.__next__()
4

ジェネレータでは、python 2とpython 3の違いpython 2がnext()python 3が__next__()generatorはアルゴリズムを保存し、g.__next__()を呼び出すたびにgの次の要素の値を計算し、最後の要素まで計算し、より多くの要素がない場合、StopIterationのエラーを投げ出すと述べた.
もちろん、このようなg.__next__()の呼び出しはあまりにも変態であり、generatorも反復可能なオブジェクトであるため、正しい方法はforループを使用することである.
code->forサイクル
>>> g = (x * x for x in range(10))
>>> for n in g:
...     print(n)
...
0
1
4
9
16
25
36
49
64
81

コードジェネレータ練習
#     
print([i * 2 for i in range(10)])
##[ function(i) for i in range(10)]

a = []
for i in range(10):
    a.append(i * 2)
print(a)

#    ,      ,         
b = (i * 2 for i in range(10))
for i in b:
    print(i)

#   ,      ,         
#       
#  ,    
c = [i * 2 for i in range(1000)]

#     ,    ,         
d = (i * 2 for i in range(1000))
#d.__next__()
print("----------")
print(len(c))
print(c[4])
print(d.__next__())
print(d.__next__())
print(d.__next__())
print(d)
# for i in d:
#     print(i)

#   ,        ,         
       ,    __next__()