はじめに
Python でオブジェクトをコピーした際にどこまで別オブジェクトとしてコピーされるかの整理です。
動作確認
コピーなし
# 共有渡し
# (同一オブジェクト)
x = ['1', ['2', '3']]
y = x
y[0] = 'A'
y[1][0] = 'B'
print(f'x = {x}') # x = ['A', ['B', '3']]
print(f'y = {y}') # y = ['A', ['B', '3']]
浅いコピー
# 浅いコピー
# (第1階層('1')は別オブジェクトになるが第2階層以降(['2, '3])は同一オブジェクト)
x = ['1', ['2', '3']]
y = list(x)
y[0] = 'A'
y[1][0] = 'B'
print(f'x = {x}') # x = ['1', ['B', '3']]
print(f'y = {y}') # y = ['A', ['B', '3']]
深いコピー
# 浅いコピー
# (全オブジェクトが別オブジェクト)
import copy
x = ['1', ['2', '3']]
y = copy.deepcopy(x)
y[0] = 'A'
y[1][0] = 'B'
print(f'x = {x}') # x = ['1', ['2', '3']]
print(f'y = {y}') # y = ['A', ['B', '3']]
参考資料
- 『Pythonトリック』
https://www.amazon.co.jp/Python%E3%83%88%E3%83%AA%E3%83%83%E3%82%AF-Dan-Bader/dp/4798157678
おわりに
Pyhonに限ったことではありませんが、特に入れ子のオブジェクトの場合は、それぞれの階層のオブジェクトの値を変更した場合、代入元と代入先のそれぞれのオブジェクトの値がどのようになるのかを意識しないと痛い目に会いそうですね。