浅いコピーと深いコピーの違い
ミュータブルなオブジェクトをコピーしたとき、そのオブジェクトの構造やコピーの仕方によっては挙動が大きく変わることがある。
単純にコピーはコピーじゃないんか?と思うけど一言にコピーと言っても同じではない。浅いコピーと深いコピーがある。
浅いコピー:Shallow Copy
深いコピー:Deep Copy
浅い深いってなんやねんって感じですけど、実際の挙動を見るのが早いですね。
例えば、以下のようなリストを代入したときと、浅いコピー、深いコピーしたときの挙動を見てみる。
import copy
l = [0,1,[2,3]]
l_assign = l
l_copy = l.copy()
l_deepcopy = copy.deepcopy(l)
def print_l():
print('list:', l)
print('assign:',l_assign)
print('copy:',l_copy)
print('deepcopy:',l_deepcopy)
l[0] = 100
print_l()
l[2][0] = 300
print_l()
まず最初の
l[0] = 100
print_l()
の出力を見ると
list: [100, 1, [2, 3]]
assign: [100, 1, [2, 3]]
copy: [0, 1, [2, 3]]
deepcopy: [0, 1, [2, 3]]
となっていて、リスト本体と代入先は同様に変更されている。 コピーした方はどちらも変わっていない。 コピーした時点で基本的には別オブジェクトとなるからで、これだけだと浅い深いの違いはわからない。
違いが出るのは、ネストされたリスト側の操作をしたとき
つまり
l[2][0] = 300
print_l()
の出力なんだけど、
list: [100, 1, [300, 3]]
assign: [100, 1, [300, 3]]
copy: [0, 1, [300, 3]]
deepcopy: [0, 1, [2, 3]]
こうなる。
浅いコピーの方にも同じ変更がされてしまっている。
つまり浅いコピーはオブジェクト中のオブジェクトはコピーされないっていうこと。
深いコピーをすれば、オブジェクト中のオブジェクトもコピーされて別オブジェクト扱いされるようになる。
ディスカッション
コメント一覧
まだ、コメントがありません