Python学習ノート3-高度な特性
2447 ワード
ジェネレータジェネレータ
リスト生成式により、リストを直接作成できます.ただし、メモリの制限を受けると、リストの容量は限られているに違いありません.
ジェネレータは、ループを繰り返しながら計算するメカニズムにより、ループの過程で後続の要素を絶えず推定し、完全なリストを作成する必要がなく、大量の空間を節約することができます.
簡単なgenerator定義例:
next()関数によりgeneratorの次の戻り値が得られ、最後の要素まで計算され、より多くの要素がない場合、
generatorも反復可能なオブジェクトであるため、forループを使用してgeneratorの戻り値を取得します.forループを使用するには
リスト生成式のようなforループでは実現できない場合,generatorを関数で実現することもできる.関数定義にyieldキーワードが含まれている場合、この関数は通常の関数ではなくgeneratorです.
generatorと関数の実行プロセスの違い:関数は順番に実行され、return文または最後の行の関数文に遭遇すると を返します. generatorの関数は、next()を呼び出すたびに実行され、yield文の戻りに遭遇し、再実行時に前回返されたyield文から を実行し続ける.
generatorのreturn文の戻り値を取得するには、
反復器
したがって、generatorはすべてIteratorオブジェクトですが、list、dict、strはIterableですがIteratorではありません
オブジェクトがIteratorオブジェクトかどうかを
リスト生成式により、リストを直接作成できます.ただし、メモリの制限を受けると、リストの容量は限られているに違いありません.
ジェネレータは、ループを繰り返しながら計算するメカニズムにより、ループの過程で後続の要素を絶えず推定し、完全なリストを作成する必要がなく、大量の空間を節約することができます.
簡単な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と関数の実行プロセスの違い:
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()
関数によって呼び出され、次の値を繰り返し返すことができるオブジェクトを反復器と呼びます.Iterator
Iteratorオブジェクトは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などのIterable
をIterator
に変更できます.isinstance(iter([]), Iterator) ==> True
isinstance(iter('abc'), Iterator) ==> True