Python で特定のサイズのリストを作成する方法
リストまたは配列用のストレージの事前割り当ては、プログラマーの間の典型的なパターンです
事前に要素の数を知っているとき。
C++ や Java とは異なり、Python では、事前に割り当てられたすべてのストレージをいくつかの値で初期化する必要があります。
通常、開発者はその目的のために、None
、''
、False
、0
などの偽の値を使用します。
Python は、固定サイズのリストを作成するいくつかの方法を提供します。
さまざまなパフォーマンス特性。
さまざまなアプローチのパフォーマンスを比較するために、Python の標準を使用します
モジュール timeit
。
Python コードの小さなチャンクの実行時間を測定する便利な方法を提供します。
リスト用のストレージの事前割り当て
指定されたリストを繰り返す *
演算子を使用する最初で最速の方法
何度か。
>>> [None] * 10
[None, None, None, None, None, None, None, None, None, None]
100 万回の繰り返し(timeit
の繰り返しのデフォルト値)には約
117 ミリ秒。
>>> timeit("[None] * 10")
0.11655918900214601
別のアプローチは、リスト内包で range
組み込み関数を使用することです。
>>> [None for _ in range(10)]
[None, None, None, None, None, None, None, None, None, None]
これはほぼ 6 倍遅く、100 万回の反復ごとに 612 ミリ秒かかります。
>>> timeit("[None for _ in range(10)]")
0.6115895550028654
3 番目のアプローチは、シンプルな for
ループを list.append()
と一緒に使用することです。
>>> a = []
>>> for _ in range(10):
... a.append(None)
...
>>> a
[None, None, None, None, None, None, None, None, None, None]
ループを使用するのが最も遅い方法であり、100 万回の反復を完了するのに 842 ミリ秒かかります。
>>> timeit("for _ in range(10): a.append(None)", setup="a=[]")
0.8420009529945673
他の順次データ構造用のストレージの事前割り当て
連続したデータ構造にストレージを事前に割り当てているため、array
組み込みデータを使用することは理にかなっているかもしれませんリストではなく構造。
>>> from array import array
>>> array('i',(0,)*10)
array('i', [0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
以下に示すように、このアプローチは [None] * 10
に次いで 2 番目に高速です。
>>> timeit("array('i',(0,)*10)", setup="from array import array")
0.4557597979946877
上記の純粋な Python アプローチを科学計算用の NumPy
Python パッケージと比較しましょう。
>>> from numpy import empty
>>> empty(10)
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
NumPy の方法では、100 万回の反復あたり 589 ミリ秒かかります。
>>> timeit("empty(10)", setup="from numpy import empty")
0.5890094790011062
ただし、より大規模なリストの場合、NumPy の方法ははるかに高速です。
>>> timeit("[None]*10000")
16.059584009999526
>>> timeit("empty(10000)", setup="from numpy import empty")
1.1065983309963485
結論は、小さなリストの場合は [None] * 10
に固執することをお勧めしますが、
より大規模なシーケンシャルデータを処理する場合の NumPy の empty()