Python学習ノート3-高度な特性

2447 ワード

ジェネレータジェネレータ
リスト生成式により、リストを直接作成できます.ただし、メモリの制限を受けると、リストの容量は限られているに違いありません.
ジェネレータは、ループを繰り返しながら計算するメカニズムにより、ループの過程で後続の要素を絶えず推定し、完全なリストを作成する必要がなく、大量の空間を節約することができます.
簡単なgenerator定義例:
#          []  (),      generator
g = (x * x for x in range(10))

next()関数によりgeneratorの次の戻り値が得られ、最後の要素まで計算され、より多くの要素がない場合、StopIterationのエラーが投げ出されます.
next(g)

generatorも反復可能なオブジェクトであるため、forループを使用してgeneratorの戻り値を取得します.forループを使用するにはStopIterationのエラーに関心を持つ必要はありません.
for n in g:
    print(n)

リスト生成式のようなforループでは実現できない場合,generatorを関数で実現することもできる.関数定義にyieldキーワードが含まれている場合、この関数は通常の関数ではなくgeneratorです.
//          generator
def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'
#      ,          

f = fib(6)
next(f)

for n in fib(6):
    print(n)

generatorと関数の実行プロセスの違い:
  • 関数は順番に実行され、return文または最後の行の関数文に遭遇すると
  • を返します.
  • generatorの関数は、next()を呼び出すたびに実行され、yield文の戻りに遭遇し、再実行時に前回返されたyield文から
  • を実行し続ける.
    generatorのreturn文の戻り値を取得するには、StopIterationエラーを取得する必要があります.戻り値はStopIterationのvalueに含まれます.forループはStopIterationエラーを取得できないためnext()しか使用できません.
    g = fib(6)
    
    while True:
        try:
            x = next(g)
            print('g:',x)
        except StopIteration as e:
            print('Generator return value:', e.value)
            break
    

    反復器next()関数によって呼び出され、次の値を繰り返し返すことができるオブジェクトを反復器と呼びます.IteratorIteratorオブジェクトはnext()関数によって呼び出され、データがないときにStopIterationエラーが投げ出されるまで次のデータを繰り返し返すことができます.このデータストリームは秩序あるシーケンスと見なすことができるが,シーケンスの長さを事前に知ることはできず,next()関数を介して次のデータをオンデマンドで計算するしかないため,Iteratorの計算は不活性であり,次のデータを返す必要がある場合にのみ計算される.
    したがって、generatorはすべてIteratorオブジェクトですが、list、dict、strはIterableですがIteratorではありません
    オブジェクトがIteratorオブジェクトかどうかをisinstance()で判断します.
    from collections import Iterator
    
    isinstance((x for x in range(10)), Iterator) ==> True
    isinstance([], Iterator) ==> False
    isinstance({}, Iterator) ==> False
    isinstance('abc', Iterator) ==> False
    
    iter()関数を使用してlist、dict、strなどのIterableIteratorに変更できます.
    isinstance(iter([]), Iterator) ==> True
    isinstance(iter('abc'), Iterator) ==> True