はじめに
Atcoder004 - Cross Sum(★2)の問題を解いている時、自分の考えている処理と異なる処理が行われた。具体的には、2次元配列をコピーする際、コピーする元の配列まで変化してしまうというエラーが発生した。自分の学習のメモとして、記事を書いた。
コード
#1次元配列の場合
a = [1,3]
b = a.dup
b[0] = 2
print a #[1, 3]
print b #[2, 3]
#2次元配列の場合
c = [[1,2],[1,3]]
d = c.dup
d[0][0] = 2
print c #[[2, 2], [1, 3]]
print d #[[2, 2], [1, 3]]
解説
1次元配列の場合、配列をコピーしたものの要素を変更しても、元の配列は変化しない。しかし、2次元配列の場合、配列をコピーしたものお要素を変更すると、元の配列も変更されてしまう。
原因は、dupやcloneなどの配列を複製するコマンドは浅いコピーであることだ。浅いコピーの場合、コピー元の配列も変更する場合が生まれてしまう。今回のように多次元配列をコピーして、コピーした配列の要素を変更するとコピー元も変更されてしまうようだ。
深いコピーをする場合、Marshalモジュールを使えばできるらしい。ただ、Marshalモジュールで複製できないオブジェクトもあるようだ。
(補足)
今回のAtcoderの問題はdupなどのコピーコマンドは使わず、transposeコマンドを使うことで問題を解くことができた。
終わりに
コピーコマンドを使用しても、コピー元の配列が変更されてしまうことがあるのを学んだ。他のプログラミング言語を学ぶ時にも、活きそうな知識だと感じた。