こんにちわlisです!
今回はPython3での、リスト(list)のコピーについてです!
代入やコピーを行ったとき、値コピーなのか参照コピーなのか……
と、わかったつもりでいて、少し離れると訳わからなくなるので試しがてらまとめてみました。
ちなみに辞書型(dict)も恐らく同じです。
結論
今回試した結果はこちら。
コピーの仕方 | 式 | 結果 |
---|---|---|
代入 | d = s | 参照がコピーされる |
値代入 | d[:] = s | 値がコピーされる |
浅いコピー | d = copy.copy(s) | 別オブジェクトでコピーされる |
深いコピー | d = copy.deepcopy(s) | 別オブジェクトでコピーされる |
それでは解説です。
下準備
まず準備として、元となるリストを作成しました。
>>> src_arr = [1, 2, 3] >>> id(src_arr) 1347790259016
こいつを代入やコピーをして、どうなるかを見ていきます。
リストをそのまま代入したとき
代入元(src_arr)と代入先(arr1)のリストを作成します。
これを単純に代入した場合です。
>>> arr1 = [] >>> id(arr1) 1347790269320 >>> arr1 = src_arr >>> id(arr1) 1347790259016 >>> id(src_arr) 1347790259016
結果は、src_arrと同じidになりました。
ということは参照(アドレス)がコピーされているため、arr1を操作するとsrc_arrも同じ操作を受けます。
参照が同じだからです。
>>> arr1[1] = 99 >>> arr1 [1, 99, 3] >>> src_arr [1, 99, 3]
リストの値をコピーする
今度は同じ代入でも「[:]」を付けて代入します。
>>> arr2 = [] >>> id(arr2) 1347790269320 >>> arr2[:] = src_arr >>> id(arr2) 1347790269320 >>> id(src_arr) 1347790259016
するとidはそのままに、値はコピーがされています。
>>> arr2 [1, 2, 3] >>> src_arr [1, 2, 3]
この状態でarr2の配列を操作しても、src_arrには影響がありません。
作業が異なりますからね。
>>> arr2[1] = 99 >>> arr2 [1, 99, 3] >>> src_arr [1, 2, 3]
copy.copy(浅いコピー)
今度はcopy.copy()を使って、浅いコピーを試します。
>>> import copy >>> arr3 = [] >>> id(arr3) 1347790269256 >>> arr3 = copy.copy(src_arr) >>> id(arr3) 1347790269320 >>> id(src_arr) 1347790259016
結果はsrc_arrとも元のarr3とも異なるidとなりました。
新しいid(オブジェクト)にコピーした値が作られて、arr3に代入された感じです。
なので配列を操作しても、影響はありません。
>>> arr3 [11, 88, 3] >>> src_arr [1, 2, 3] >>> arr3[1] = 99 >>> src_arr[1] = 88 >>> arr3 [11, 99, 3] >>> src_arr [1, 88, 3]
更にいうと、元のarr3のid(参照)をコピーしておいて、各々配列を操作すると、独立したオブジェクトであることがわかります。
>>> a = [] >>> a = arr3 >>> arr3 = copy.copy(src_arr) >>> >>> a[0] = 10 >>> arr3[0] = 11 >>> src_arr[0] = 12 >>> a [10, 99, 3] >>> arr3 [11, 88, 3] >>> src_arr [12, 88, 3]
copy.deepcopy(深いコピー)
copy.deepcopy()を使って、深いコピーを試します。
>>> arr4 = [] >>> id(arr4) 1347790269256 >>> arr4 = copy.deepcopy(src_arr) >>> id(arr4) 1347790291656 >>> id(src_arr) 1347790259016
浅いコピー同様、どれとも一致しないidとなりました。
これも同じく各々独立したオブジェクトとしてコピーがされました。
>>> arr4 [1, 2, 3] >>> src_arr [1, 2, 3] >>> arr4[1] = 99 >>> src_arr[1] = 88 >>> arr4 [1, 99, 3] >>> src_arr [1, 88, 3] >>> >>> b = [] >>> b = arr4 >>> arr4 = copy.deepcopy(src_arr) >>> >>> b[0] = 10 >>> arr4[0] = 11 >>> src_arr[0] = 12 >>> a [10, 99, 3] >>> arr4 [11, 88, 3] >>> src_arr [12, 88, 3]
あとがき
今回はPython3での、リストのコピーについてでした!
こう並べてみるとなるほどって感じです。
が、少し離れると忘れるときがあるので、メモですね。
みなさんももし忘れたら参考にしてみてください!
インタプリタでちゃちゃっと試した方が早いかもしれませんが(笑)