ドキュメントテキストは、オーバーヘッドを回避するためにジェネレータを構築する方法についてではありません。例で提供されているコードなど、正しく記述itertools
されたコードを使用すると、forループとジェネレーターが完全に回避され、イテレーターを使用するためにitertoolsまたは組み込みコレクター(などlist
)に任せられることが説明されています。
たとえば、次のtabulate
例を見てください。
def tabulate(function, start=0):
"Return function(0), function(1), ..."
return imap(function, count(start))
これを書くためのベクトル化されていない方法は次のようになります。
def tabulate(function, start=0):
i = start
while True:
yield function(i)
i += 1
このバージョンでは、ループと関数呼び出しがPythonで行われるため、「インタープリターのオーバーヘッドが発生します」。
単一の要素のチェーンに関しては、chain(sequence, [obj])
固定長のリストの構築が特殊な構文とオペコードを使用してPythonで十分に最適化されているため、(自明に)高速になると考えるのが安全です。同様chain(sequence, (obj,))
に、タプルはリストの最適化を共有し、起動するのが小さいため、さらに高速になります。python -m timeit
ベンチマークではいつものように、推測するよりも測定する方がはるかに優れています。
ドキュメントの引用は、とのいずれかを選択することによって示されるものなど、イテレータの作成の違いとは関係ありません。イテレータは単一の要素しか生成しないため、消費方法に違いはありません。ドキュメントでは、数百万の要素を生成する可能性のあるイテレータを処理する際のプロセッサとメモリの効率について説明しています。それに比べて、作成戦略はいつでも変更できるため、作成速度が速いイテレーターを選択するのは簡単です。一方、ベクトル化しない明示的なループを使用するようにコードが設計されると、完全に書き直さずに後で変更するのは非常に困難になる可能性があります。repeat(foo, 1)
[foo]