[Python]参照渡しバグ?

import numpy as np

ntot = 15

G1 = np.zeros((ntot,3))
for i in range(0,ntot):
    G1[i]=np.array([1.0,1.0,1.0])


G2 = np.zeros((ntot,3))
for i in range(0,ntot):
    G2[i]=np.array([1.0,1.0,1.0])

vlist=[]
for idx1 in range(0,ntot):
    for idx2 in range(0, ntot):
        vecs = [G1[idx1],G2[idx2]]
        vlist.append(vecs)

print("rlist100",vlist[1][0][0])
vlist[0][0][0] = vlist[0][0][0] + 1.0
print("rlist100",vlist[1][0][0])

これは二つの配列G1, G2からなる配列をvlistにappendしていくコード。最後の3行で、[1][0][0]成分をチェック-->[0][0][0]成分に1足す-->[1][0][0]成分をチェックとしている。この操作では[1][0][0]には何もしていないにもかかわらず、出力は以下の通り

rlist100 1.0
rlist100 2.0

[1][0][0]成分が変化している。

オーケー。pythonは変数代入においてアドレスを渡してるだけの場合があるのでおそらくそれのせいでしょう。ということで問題の配列成分のアドレスを見てみましょうね。

print("id000",id(vlist[0][0][0]))
print("id100",id(vlist[1][0][0]))

出力してみると

id000 140486238474160
id100 140486238473808

( ^ω^)・・・
ちゃんとアドレス違ってる。。

よし、もう全部アドレス書いてみよう!

print("id",id(vlist))
print("id0",id(vlist[0]))
print("id1",id(vlist[1]))
print("id00",id(vlist[0][0]))
print("id10",id(vlist[1][0]))
print("id000",id(vlist[0][0][0]))

出力は

rlist100 1.0
rlist100 2.0
id 139799451592320
id0 139799472742848
id1 139799451591680
id00 139799480417808
id10 139799451581968
id000 139799453745072
id100 139799453744720

どういうこと( ^ω^)・・・


なぜか動く

いや、どう考えてもアドレスの問題やろと信じていろいろ試していたのですが、結局以下の修正で解決

import numpy as np
import copy # 改変

ntot = 15

G1 = np.zeros((ntot,3))
for i in range(0,ntot):
    G1[i]=np.array([1.0,1.0,1.0])


G2 = np.zeros((ntot,3))
for i in range(0,ntot):
    G2[i]=np.array([1.0,1.0,1.0])

vlist=[]
for idx1 in range(0,ntot):
    for idx2 in range(0, ntot):
        vecs = [copy.copy(G1[idx1]),copy.copy(G2[idx2])]  #改変
        vlist.append(vecs)

print("rlist100",vlist[1][0][0])
vlist[0][0][0] = vlist[0][0][0] + 1.0
print("rlist100",vlist[1][0][0])

出力は

rlist100 1.0
rlist100 1.0

ということでOK。
しかしアドレスを見ると…


print("id000",id(vlist[0][0][0]))
print("id100",id(vlist[1][0][0]))

出力は

id000 139782151499344
id100 139782151499344

どういうこと?

いいなと思ったら応援しよう!