雑多なブログ

音楽や語学、プログラム関連の話題について書いています

python: リストのコピー

リストのコピー

pythonのリストを別の変数に代入すると、値のコピーでなく参照が設定される。 そのため、代入した変数でリストの要素を変更すると、代入元のリストの内容も書き換わる。

例) 値が書き換わる例

>>> a = [1, 2, 3]
>>> b = a
>>> b.append(9999)
>>> a
[1, 2, 3, 9999]
>>> a = [1, 2, 3, 4]
>>> b = a
>>> b.append(9)
>>> b
[1, 2, 3, 4, 9]
>>> a
[1, 2, 3, 4, 9]

参照ではなく、値をコピーする場合、次の方法があるようだ。

  • スライスを使う
  • copyモジュールを使う

スライスでリストをコピーする場合

>>> c = a[:]
>>> c
[1, 2, 3, 4, 9]
>>> c.append(9999)
>>> a
[1, 2, 3, 4, 9]

copyモジュールを使う場合

import copyモジュールを使う

コピーには浅いコピーと深いコピーがあるようだ。 浅いコピー(copy.copy)の場合は、リスト内のリストまではコピーしてくれず、参照になってしまう。そのため、子要素の値を変更すると代入元と代入先のリストで値が書き換わってしまう。

>>> a = [[1, 2], [3, 4]]
>>> b = copy.copy(a)
>>> a[0][0] = 9
>>> b
[[9, 2], [3, 4]]
>>> import copy
>>> a
[1, 2, 3, 4, 9]
>>> d = copy.deepcopy(a)
>>> d.append(99999)
>>> d
[1, 2, 3, 4, 9, 99999]
>>> a
[1, 2, 3, 4, 9]

ということで、多次元のリストをコピーする場合は、copy.deepcopy() を使う。

>>> import copy
>>> l = [[1,2],[3,4],[5,6],[7,8]]
>>> d = copy.deepcopy(l)
>>> d
[[1, 2], [3, 4], [5, 6], [7, 8]]
>>> d[0][1] = 4
>>> d
[[1, 4], [3, 4], [5, 6], [7, 8]]
>>> l
[[1, 2], [3, 4], [5, 6], [7, 8]]

deepcopyでリストを複製すると新しい多次元のリストの要素を変更しても、元のリストの値は書き変わらない。