python3 値渡しと参照渡し
python3 覚え書きNo.5
pythonの変数への代入はすべて参照渡しです。でも、値渡しをしたい時ってありますよね。私がC言語からプログラミングに入ったからでしょうか。
la = [[1, 2, 3], [4, 5, 6]] lb = la print(lb) lb[0][0] = 777 print(la) 実行結果 [[1, 2, 3], [4, 5, 6]] [[777, 2, 3], [4, 5, 6]]
このようにリストlbにリストlaを代入した後、lbの値を変更するとlaの値も変更されます。laとlbがメモリの同一領域を参照しているからです。
これを防ぐためにはモジュールcopyのdeepcopy関数を利用します。
from copy import deepcopy la = [[1, 2, 3], [4, 5, 6]] lb = deepcopy(la) la[0][0] = 777 print(la) print(lb) 実行結果 [[777, 2, 3], [4, 5, 6]] [[1, 2, 3], [4, 5, 6]]
今度はリストlaの値を変更しても、lbの値が変更されていません。iteratorも値渡し出来ました。
numpy配列の値渡し
また、numpyを利用している場合、numpyのcopy関数を利用できます。
import numpy as np npla = np.array([[1, 2, 3], [4, 5, 6]]) nplb = npla.copy() npla[0, 0] = 777 print(npla) print(nplb) 実行結果 [[777 2 3] [ 4 5 6]] [[1 2 3] [4 5 6]]
値渡しが出来ていることが分かります。
ただし以下の場合のように、numpy配列の中にリストが入っているような形式だとcopy関数を利用しても中のリストは参照渡しになるようです。
import numpy as np npla = np.array([[1, 2, 3], [4, 5]]) nplb = npla.copy() npla[0][0] = 777 print(npla) print(nplb) 実行結果 [list([777, 2, 3]) list([4, 5])] [list([777, 2, 3]) list([4, 5])]