今私はリストを使っていて、次のようなものを期待していました。
verts = list (1000)
代わりにarrayを使うべきですか?
私にとって頭に浮かぶのは、次のとおりです。
verts = [None]*1000
しかし、あなたは本当にそれを事前に初期化する必要がありますか?
誰もがこれをやりたいと思うのに苦労している理由がよくわからない - 固定サイズの初期化リストが欲しいと思うシナリオがいくつかある。そして、あなたは正しく配列がこれらの場合に賢明であると推測しました。
import array
verts=array.array('i',(0,)*1000)
Python以外の人にとっては、(0,)*1000
という用語は1000個のゼロを含むTupleを作成しています。コンマはpythonに(0)
をTupleとして認識させる。そうでなければ0として評価されるだろう。
私はリストの代わりにTupleを使いました。それらは一般的にオーバーヘッドが少ないからです。
1つの明白でおそらく効率的でない方法は
verts = [0 for x in range(1000)]
これは簡単に2次元に拡張できることに注意してください。たとえば、10 x 100の「配列」を取得するには、次のようにします。
verts = [[0 for x in range(100)] for y in range(10)]
固定サイズの配列を初期化したいのであれば、どのプログラミング言語でも実行可能です。プログラマーがbreakステートメントをwhile(true)ループに入れたいのではありません。特に、多くの動的計画法のアルゴリズムのように、要素が単に上書きされて単純に加減算されないのであれば、appendステートメントや要素が削除されていないかどうかをチェックしたくないでしょうまだオンザフライで初期化されています(それはたくさんのコードの紳士です)。
object = [0 for x in range(1000)]
これはプログラマーが達成しようとしていることのために働くでしょう。
@Steveはすでにあなたの質問に良い答えを出しています:
verts = [None] * 1000
警告:@Joachim Wuttkeが指摘したように、リストは不変要素で初期化されなければなりません。 [[]] * 1000
は期待通りには動きません。なぜならあなたは1000個の同一のリストのリストを得るからです(Cの同じリストへの1000ポイントのリストに似ています)。 int、str、Tupleなどの不変のオブジェクトでもうまくいきます。
リストのサイズ変更は遅いです。次の結果はそれほど驚くべきことではありません。
>>> N = 10**6
>>> %timeit a = [None] * N
100 loops, best of 3: 7.41 ms per loop
>>> %timeit a = [None for x in xrange(N)]
10 loops, best of 3: 30 ms per loop
>>> %timeit a = [None for x in range(N)]
10 loops, best of 3: 67.7 ms per loop
>>> a = []
>>> %timeit for x in xrange(N): a.append(None)
10 loops, best of 3: 85.6 ms per loop
しかし、非常に大きなリストがなければ、サイズ変更はそれほど遅くありません。リストのサイズを変更しないように単一の要素(None
など)と固定長でリストを初期化する代わりに、リスト内包表記を使用してリストに正しい値を直接入力することを検討してください。例えば:
>>> %timeit a = [x**2 for x in xrange(N)]
10 loops, best of 3: 109 ms per loop
>>> def fill_list1():
"""Not too bad, but complicated code"""
a = [None] * N
for x in xrange(N):
a[x] = x**2
>>> %timeit fill_list1()
10 loops, best of 3: 126 ms per loop
>>> def fill_list2():
"""This is slow, use only for small lists"""
a = []
for x in xrange(N):
a.append(x**2)
>>> %timeit fill_list2()
10 loops, best of 3: 177 ms per loop
巨大なデータセットや、他の最適化されたライブラリの方がはるかに高速です。
from numpy import ndarray, zeros
%timeit empty((N,))
1000000 loops, best of 3: 788 ns per loop
%timeit zeros((N,))
100 loops, best of 3: 3.56 ms per loop
あなたはこれをすることができます:
verts = list(xrange(1000))
それはあなたにサイズが1000個の要素のリストを与え、それは0-999の値で初期化されることが起こるでしょう。 list
は新しいリストのサイズを決めるために__len__
を最初にするので、それはかなり効率的であるべきです。
この:
lst = [8 for i in range(9)]
リストを作成し、要素は初期化されます8
でも、これ:
lst = [0] * 7
1つの要素を持つ7つのリストを作成します
あなたは事前に初期化されたリストの代わりにdict
型を使うことを検討するべきです。辞書検索のコストは小さく、任意のリスト要素にアクセスするコストに匹敵します。
そして、マッピングを使うとき、あなたは書くことができます:
aDict = {}
aDict[100] = fetchElement()
putElement(fetchElement(), fetchPosition(), aDict)
そしてputElement
関数は任意の位置にitemを格納することができます。そして、あなたのコレクションが与えられたインデックスの要素を含んでいるかどうかをチェックする必要があるなら、書くのはもっとPythonicです:
if anIndex in aDict:
print "cool!"
より:
if not myList[anIndex] is None:
print "cool!"
後者はあなたのコレクションの本当の要素がNone
になることはできないと仮定しているので。そしてそれが起こるなら - あなたのコードは誤動作します。
そして、あなたがパフォーマンスを切実に必要としていて、それであなたがあなたの変数を事前に初期化し、そして可能な限り最速のコードを書くことを試みる理由 - あなたの言語を変えなさい。最速のコードはPythonで書くことはできません。代わりにCを試して、ラッパーを実装してPythonから事前初期化および事前コンパイルされたコードを呼び出すようにしてください。