2012-05-16 13 views
22

は、私は、私はちょうど..のようないくつかの項目を追加、またはより、私はリストを宣言することができることを知っている...のようなPythonでpythonで固定サイズのリストを作成するには? C++で

int* a = new int[10]; 

を配列を作成することができ

l = [1,2,3,4] 
l = range(10) 

C++のような指定されたサイズでリストを初期化できますか?割り当てをしないでください。

+2

あなたはPythonでリストを宣言するために_do_ _not_ _need_を使用します。あなたがそれを望んでいるときにそれを初期化してください。 – ronakg

+4

そうですね、なぜあなたはそれを必要としますか? – 0605002

+0

PythonはC++ではありません。あなたは本当にあなたがそれについて考える方法を変更する必要がある、Pythonで固定サイズを宣言する必要はありません。 – WeaselFox

答えて

28

(TL; DR:あなたの質問に正確な答えがnumpy.emptynumpy.empty_likeですが、あなたはおそらく気にしないとmyList = [None]*10000を使用して逃げることができます。)

シンプルな方法

ますあなたのリストをすべて同じ要素に初期化できます。意味のない数値を使うことは意味があるのですか(それは後でエラーを出す、良いことです)、0のようなものです(珍しいでしょうか?疎な行列や 'デフォルト」の値は0にしてください、あなたはバグを心配しないでね)あなた次第です:

>>> [None for _ in range(10)] 
[None, None, None, None, None, None, None, None, None, None] 

(ここ_あなたがiを使用することもでき、単に変数名です)

あなたがすることもできます。このようにしてください:

>>> [None]*10 
[None, None, None, None, None, None, None, None, None, None] 

これを最適化する必要はありません。簡単な方法

最善であるの

>>> x = [] 
>>> for i in range(10): 
>>> x.append(i) 

性能比較:あなたはまた、アレイにあなたが必要とするたびに追加することができますか? python2.7で

>>> def initAndWrite_test(): 
... x = [None]*10000 
... for i in range(10000): 
... x[i] = i 
... 
>>> def initAndWrite2_test(): 
... x = [None for _ in range(10000)] 
... for i in range(10000): 
... x[i] = i 
... 
>>> def appendWrite_test(): 
... x = [] 
... for i in range(10000): 
... x.append(i) 

結果:パイソン3.2で

>>> import timeit 
>>> for f in [initAndWrite_test, initAndWrite2_test, appendWrite_test]: 
... print('{} takes {} usec/loop'.format(f.__name__, timeit.timeit(f, number=1000)*1000)) 
... 
initAndWrite_test takes 714.596033096 usec/loop 
initAndWrite2_test takes 981.526136398 usec/loop 
appendWrite_test takes 908.597946167 usec/loop 

結果:

initAndWrite_test takes 641.3581371307373 usec/loop 
initAndWrite2_test takes 1033.6499214172363 usec/loop 
appendWrite_test takes 895.9040641784668 usec/loop 

我々が見ることができるように、それは両方のpython2でイディオム[None]*10000を行うには可能性が優れているとpython3。しかし、割り当てよりも複雑なもの(リスト内のすべての要素を生成または処理するのが複雑なものなど)を実行している場合、オーバーヘッドは無意味にコストの一部になります。つまり、このような最適化は、あなたのリストの要素に合理的な何かをしているかどうかを心配するのは時期尚早です。彼らはプロセスで何かを書いて、メモリを経由するので


初期化されていないメモリ

これらはすべてが非効率的です。 Cでは、初期化されていない配列はランダムなガベージメモリ(システムから再割り当てされたもので、プログラムを閉じるときにメモリを割り当てたり、メモリを削除しなかったときにsecurity riskになる可能性があります) 。これは設計の選択であり、高速化のために設計されています.C言語のメーカーは、自動的にメモリを初期化しない方が良いと考えていました。

これは漸進的なスピードアップ(O(N)なので)ではありませんが、実際に気にしているもので上書きする前に、メモリブロック全体を最初に初期化する必要はありません。可能であれば、これは(擬似コード)x = list(size=10000)のようなものです。

Pythonで同様のことをしたい場合は、numpy数値行列/ N次元配列操作パッケージを使用できます。具体的には、numpy.emptyまたはnumpy.empty_like

これはあなたの質問に対する真の答えです。

+0

'_'は、範囲を反復するときに本当に必要のない変数の単なる"ダム "な名前ですか?私はちょうど 'のために範囲(10)'が時々書き込まれることを望む。 –

+0

'x = [[None]] * 10'は「間違っています」。 'x [0] .append(1)'を試して、その魔法を見てください。 –

+0

@ Death-Stalker:そうですね、それは私が実際に指摘しようとしていたものだと思います(「可変オブジェクトを扱う」)。しかし、ありがとう、私はあなたが私の答えが恐ろしく言われていることを実現させたと思う。一定。 – ninjagecko

3

このようなリストを初期化するのは、実際にはPythonの方法ではありません。とにかく、次のようなリストを初期化することができます:

>>> l = [None] * 4 
>>> l 
[None, None, None, None] 
3

これをサポートするための組み込み関数はありません。私が追加すると、つまり多くのオーバーヘッドが追加されるとは思わないので、実際にそれを最適化する必要がありますか?

ただし、l = [None] * 1000のようにすることができます。

また、ジェネレータを使用することもできます。

+0

私はPythonのメモリ管理にはあまりよく慣れていませんが、私は気が変わります。ありがとう〜 – wtm

1
your_list = [None]*size_required 
7

[None] * 10を使用できます。しかし、これは "固定サイズ"ではなく、あなたがまだ追加、削除することはできません...これはリストの作成方法です。

幅を固定するタプル(tuple([None] * 10))にすることもできますが、変更することはできません(すべての場合ではなく、格納されたアイテムが変更可能な場合のみ)。

要件に近いもう1つのオプションはリストではなく、最大長のcollections.dequeです。それは最大のサイズですが、それはもっと小さいかもしれません。

import collections 
max_4_items = collections.deque([None] * 4, maxlen=4) 

しかし、リストを使用して、 "pythonic"なやり方で慣れてください。

3

も注意してください、あなたがC++での配列を使用するときにPythonでさまざまな方法で解決される多少異なるニーズ、持っていたかもしれないことを:

  1. あなたはアイテムのちょうどコレクションを必要としているかもしれませんが。 Pythonはこのユースケースを完全に扱っています。
  2. アレイの同種のアイテムが必要な場合があります。 Pythonのリストはではないの配列を保存する良い方法です。

Pythonは他のニートとりわけ、既知のサイズのアレイを作成する方法があり、NumPyによってアレイにおける必要性を解決:

from numpy import * 

l = zeros(10) 
+6

'from numpy import *'を使用すると、python組み込み関数の 'all'、' abs'、 'min'、' max'、 'sum'、' any'、 'round'がnumpyの等価関数で隠されます。あなたが欲しいもの。 –

+2

はい、 'numpy'モジュールにかなりの名前が含まれていることに注意してください(それでも、配列コードを書くときにモジュールの名前空間に入れるのが便利です)。名前の衝突が起こる可能性がある場合は、問題が発生します。修飾されたインポートを使用してください。 – ulidtko

0
fix_array = numpy.empty(n, dtype = object) 

nはあなたの配列のサイズは

ですが、この目的のためにライブラリをインポートしなければならない場合があります。お役に立てれば!

関連する問題