目次

目次

Pythonにおけるリストのコピー

アバター画像
海津 純平
アバター画像
海津 純平
最終更新日2018/01/30 投稿日2018/01/30

はじめに

昔、Pythonのリストのコピーでつまずいた話になります。 同じミスがないように。。。と思い共有します。

環境

  • Python 3.6.3

リストのコピー

以下のようにリストを代入しただけだと

l1 = [1, 2, 3]
l2 = l1
l2[0] = 10  #l2のみ最初の値を変えたい
print('l1:', l1)
print('l2:', l2)

実行結果

l1: [10, 2, 3]
l2: [10, 2, 3]

l2だけを変更したつもりが、l1まで変わってしまいました。 リストの場合、単純な代入だけでは同じオブジェクトを参照してしまいます。 C++を書いているときも似たようなことがあったので、 コピーをしなければならないと思いました。 ということで、以下のようなコードで

import copy
l1 = [1, 2, 3]
l2 = copy.copy(l1) #コピーを行う
l2[0] = 10
print('l1:', l1)
print('l2:', l2)

実行結果

l1: [1, 2, 3]
l2: [10, 2, 3]

コピーをすることで別のオブジェクトになり、ちゃんと l2の値だけが変わりました。

多次元リストのコピー

多次元のリストでも同じように書いたのですが

import copy
l1 = [[1, 2, 3], [4, 5, 6]]
l2 = copy.copy(l1)
l2[0][0] = 10
print('l1:', l1)
print('l2:', l2)

実行結果

l1: [[10, 2, 3], [4, 5, 6]]
l2: [[10, 2, 3], [4, 5, 6]]

!? l2だけを変えたつもりが、l1まで変わってしまいました。

浅いコピーと深いコピー

Python(というかプログラミング全般)には 浅いコピー copy深いコピー deepcopyがあるようです。 浅いコピーでは、オブジェクト内のオブジェクトまでコピーをしてくれません。 深いコピーでは再帰的にコピーを行うため、以下のようなコードにしたら

import copy
l1 = [[1, 2, 3], [4, 5, 6]]
l2 = copy.deepcopy(l1) #深いコピーにする
l2[0][0] = 10
print('l1:', l1)
print('l2:', l2)

実行結果

l1: [[1, 2, 3], [4, 5, 6]]
l2: [[10, 2, 3], [4, 5, 6]]

ちゃんと l2の値だけが変わってくれました。

まとめ

単純にコピーと言っても、浅いコピー(シャローコピー)と深いコピー(ディープコピー)がありました。

アバター画像

海津 純平

目次