当時は重複に気づかなかったようですので、重複への回答の抜粋をここにも投稿します。
より大きな入力に対するスワップのスラッシングと再割り当てのオーバーヘッドを回避するために ( とは異なり)固定のメモリ オーバーヘッド動作を維持しながら、反復可能オブジェクトが長い場合よりも有意に高速に実行する方法がありsum(1 for i in it)
ます (反復可能オブジェクトが短い場合でもそれほど遅くはありません) 。len(list(it))
# On Python 2 only, get zip that lazily generates results instead of returning list
from future_builtins import zip
from collections import deque
from itertools import count
def ilen(it):
# Make a stateful counting iterator
cnt = count()
# zip it with the input iterator, then drain until input exhausted at C level
deque(zip(it, cnt), 0) # cnt must be second zip arg to avoid advancing too far
# Since count 0 based, the next value is the count
return next(cnt)
と同様len(list(it))
に、ilen(it)
CPython で C コードのループを実行します ( 、deque
すべてC で実装されています)。通常、ループごとのバイト コードの実行を回避することが、CPython でのパフォーマンスの鍵となります。count
zip
ここですべてのパフォーマンス数値を繰り返すのではなく、完全なパフォーマンスの詳細とともに私の回答を示します。