2011-06-15 13 views
1

可能性の重複:
Python list problem初期化行列

私はPythonで行列を初期化してみてください。 は、まず、私はこのでした:私は最初のものを変更したときに

>>> M=[[0]*4]*4 

しかし、ここでは私のproblemeで、すべての行が変更されています

>>> M 
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] 
>>> M[1][1]=1 
>>> M 
[[0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0]] 

をだから私はこのようにそれをやった:

>>> M= [ [ 0 for i in range(4) ] for j in range(4) ] 

うまく動作します:

>>> M 
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] 
>>> M[1][1]=1 
>>> M 
[[0, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] 

私の質問は:

これら2つの表現は本当に何を意味していますか?なぜ最初の人がこのように行動しているのでしょうか?

ご協力いただきありがとうございます。

答えて

1

と言ってくださいaはいくつかのpythonオブジェクトです。 [a] * 4は、[a、a、a、a]と等価です。これが意味することは、aであるかどうかによって異なります。かどうかによって異なります。数値、文字列、タプルはそうではないので、aがこれらのオブジェクトの1つ(例では0)の場合、4つの独立して変更可能なコピーが得られます。リスト、辞書、セットは変更可能です。この場合、同じオブジェクトへの4つの参照があります。リストの場合は[0] * 4です。この知識を活用すれば、次のことが可能になることがわかります。

M = [[0] * 4 for i in range(4)] 

あなたが望むものを手に入れましょう。

2

ここからM=[[0]*4]*4 オブジェクトにリンクを作成します。

それは、私が参照を意味

>>> a = [0, 0, 0] 
>>> b = [a,a,a] 
>>> b 
[[0, 0, 0], [0, 0, 0], [0, 0, 0]] 
>>> a[1] = 1 
>>> b 
[[0, 1, 0], [0, 1, 0], [0, 1, 0]] 
>>> 

UPDリンクと同様だ少し混乱

3

あなたはこれらのリストを掛けるときにあれば申し訳ありませんが、Pythonは参照することにより、それらをコピーするのではなく、まったく新しいオブジェクトを作成しています。

簡単な例を参照することによりコピーして何が起こるかを示す、役立つかもしれないが:乗じてリストを構築するときに同じリストにpie_copyとパイのポイントは、すべてのコピーが指すのと同様に

>>> pie = ['apple', 'cherry', 'pecan'] 
>>> pie_copy = pie 
>>> pie_copy[0] = 'banana' 
>>> pie 
['banana', 'cherry', 'pecan'] 
>>> pie is pie_copy 
True 
>>> new_pie = ['banana', 'cherry', 'pecan'] 
>>> pie is new_pie 
False 

同じリスト

range()を使用する2番目のスニペットでは、リスト内包表記を使用して1つのリストを作成し、それを複数回コピーすることはありません。理解の各反復は新しいリストを作成しているので、参照による同じコピーの問題に苦しむことはありません。