2017-12-27 20 views
0

for loopで行列/リストを設定したいのですが、同じメソッドの1Dリストと2Dリストの間に異なる結果が観察されました。私はこれがforループを通じてリストを作成するばかげた方法だと知っていますが、誰かが私に何か違いをもたらしたヒントを与えることができますか?リストと行列のforループの反復子

m = [[0] * 4] * 4 
print m 
m[0] = range(4) 
for i in range(4): 
    m[i][0] = i 
print m 

、結果は次のとおりです。

[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] 
[[0, 1, 2, 3], [3, 0, 0, 0], [3, 0, 0, 0], [3, 0, 0, 0]] 

私は[[0, 1, 2, 3], [1, 0, 0, 0], [2, 0, 0, 0], [3, 0, 0, 0]]であることを期待していました。それは私が予想通りそれは[0,1,2,3]を印刷

tmp = [0,0,0,0] 
for i in range(4): 
    tmp[i] = i 
print tmp 

以下のように1次元リストで見つける働いていたが 。取得する

+1

Noooo、ネストされたリストに '*'を使わないでください。参照のみを複製しています。 –

答えて

0

m = [[0] * 4] * 4を実行しているときは、すべて0の2次元行列を作成しています。言い換えれば、4つの[0、0、0、0]リストのリスト。今、m[0] = range(4)で、最初の内部リストを[0,1,2,3]に設定しています。今度は、

for i in range(4): 
    m[i][0] = i 

あなたは、それぞれの内側リストの最初の要素が変更されることを期待しています。これは、Pythonのクイック・クイック・イン・オブ・オブジェクトです。最初に2Dリストを作成するときは、基本的に4つのインデックスのそれぞれから1つのリストを参照しています。次にm[0]を別のリスト(m[0] = range(4))に置き換えます。ただし、すべてのインデックスは同じリストオブジェクト[0、0、0、0]を参照します。最終的にループが終了すると、iの値は3になり、リストの最初の要素に割り当てられます。そして、インデックス1では、mの2と3がそのリストを参照していたので、3つとも同じ - [3、0、0、0]と表示されます。お役に立てれば。

1

変更最初の行:

#m = [[0] * 4] * 4 
m = [([0] * 4) for _ in range(4)] 
print m 
m[0] = range(4) 
for i in range(4): 
    m[i][0] = i 
print m 

を前に、何が起こったのは、あなたが同じリストの4つのコピーを作成したということでした。各コピーは同じメモリ空間を調べます。 Pythonはメモリを節約するためにこれを行います。したがって、リストの1つに書き込むたびに、実際にそれらのすべてに書き込むことになります。最後に書き込む値は3であるため、すべてのリストで値を取得できます。

関連する問題