Pythonには、リスト、辞書、セットなどのオブジェクトをコピーするための方法がいくつかあります。これらの方法は、オブジェクトの種類によって異なる動作をします。ここでは、初心者向けのPythonのコピーについて解説します。
# 浅いコピー(オブジェクトのcopy関数)
NEWOBJECT = OBJECT.copy()
# 浅いコピー(copyモジュールのcopy関数)
NEWOBJECT = copy.copy(OBJECT)
# 深いコピー(copyモジュールのdeepcopy関数)
NEWOBJECT = copy.deepcopy(OBJECT)
下記の様な内容で悩んでいる/困っている場合に使える方法を参考までにご共有させて頂きます。
・Pythonでは、どの様に要素をコピーするの?
・Pythonのcopy関数やdeepcopy関数は、どの様に使うのだろうか?
・Pythonのcopy関数やdeepcopy関数は、どの様な違いがあるのだろう?
浅いコピーと深いコピーの方法
Pythonでオブジェクトをコピーする方法には、浅いコピーと深いコピーの2つがあります。
浅いコピーの方法(オブジェクトのcopy関数およびcopy.copy())
浅いコピーは、コピー元のオブジェクトの参照をコピー先のオブジェクトに渡すことを指します。つまり、コピー元のオブジェクトとコピー先のオブジェクトが同じオブジェクトを参照することになります。そのため、コピー先のオブジェクトを変更すると、元のオブジェクトも変更されます。
以下は、リストの浅いコピーを行う方法です。
新しいオブジェクト = オリジナルオブジェクト.copy()
もしくは、以下の様にcopyモジュールを使用します。
import copy
新しいオブジェクト = copy.copy(オリジナルオブジェクト)
深いコピーの方法(copy.deepcopy())
深いコピーは、コピー元のオブジェクトの中身を再帰的にコピーして新しいオブジェクトを作成することを指します。つまり、コピー元のオブジェクトとコピー先のオブジェクトは、別々のオブジェクトを参照することになります。そのため、コピー先のオブジェクトを変更しても、元のオブジェクトは変更されません。
以下は、リストの深いコピーを行う方法です。
import copy
新しいオブジェクト = copy.deepcopy(オリジナルオブジェクト)
コピー方法による違い
一次元配列における一般的な参照によるコピー (B=A)
original_list = [1, 2, 3]
copy_list = original_list
copy_list[0] = 999
print(f"original: {original_list}")
print(f"copy: {copy_list}")
original: [999, 2, 3]
copy: [999, 2, 3]
上記の様に、copy_listを編集するとoriginal_listの全要素が変化します。
二次元配列における一般的な参照によるコピー (B=A)
original_list_2d = [[1,2], [3,4], [5,6]]
copy_list_2d = original_list_2d
copy_list_2d[0] = 999
copy_list_2d[1][0] = -1
print(f"original: {original_list_2d}")
print(f"copy: {copy_list_2d}")
original: [999, [-1, 4], [5, 6]]
copy: [999, [-1, 4], [5, 6]]
上記の様に、一次元配列と同様、copy_list_2dを編集するとoriginal_list_2dの全要素が変化します。
一次元配列における浅いコピーによるコピー (B=A.copy())
original_list = [1, 2, 3]
copy_list = original_list.copy()
copy_list[0] = 999
print(f"original: {original_list}")
print(f"copy: {copy_list}")
original: [1, 2, 3]
copy: [999, 2, 3]
上記の様に、一次元配列の場合、copy_listを編集したとしてもoriginal_listは変化しません。
二次元配列における浅いコピーによるコピー (B=A.copy())
original_list_2d = [[1,2], [3,4], [5,6]]
copy_list_2d = original_list_2d.copy()
copy_list_2d[0] = 999
copy_list_2d[1][0] = -1
print(f"original: {original_list_2d}")
print(f"copy: {copy_list_2d}")
original: [[1, 2], [-1, 4], [5, 6]]
copy: [999, [-1, 4], [5, 6]]
上記の様に、二次元配列の場合、”copy_list_2d[0] = 999”における編集はoriginal_list_2dへの影響はありませんが、”copy_list_2d[1][0] = -1”における編集はoriginal_list_2dの要素も変化します。浅いコピーという意味はこの様な特徴から言われております。
copyモジュールのcopy関数もオブジェクトのcopy関数と処理的には同じではございますが、以下に示します。
一次元配列における浅いコピーによるコピー (B=copy.copy(A))
original_list = [1, 2, 3]
copy_list = copy.copy(original_list)
copy_list[0] = 999
print(f"original: {original_list}")
print(f"copy: {copy_list}")
original: [1, 2, 3]
copy: [999, 2, 3]
二次元配列における浅いコピーによるコピー (B=copy.copy(A))
original_list_2d = [[1,2], [3,4], [5,6]]
copy_list_2d = copy.copy(original_list_2d)
copy_list_2d[0] = 999
copy_list_2d[1][0] = -1
print(f"original: {original_list_2d}")
print(f"copy: {copy_list_2d}")
original: [[1, 2], [-1, 4], [5, 6]]
copy: [999, [-1, 4], [5, 6]]
一次元配列における深いコピーによるコピー (B=copy.deepcopy(A))
original_list = [1, 2, 3]
copy_list = copy.deepcopy(original_list)
copy_list[0] = 999
print(f"original: {original_list}")
print(f"copy: {copy_list}")
original: [1, 2, 3]
copy: [999, 2, 3]
上記の様に、一次元配列の場合、他の方法と同様、copy_listを編集したとしてもoriginal_listは変化しません。
二次元配列における深いコピーによるコピー (B=copy.deepcopy(A))
original_list_2d = [[1,2], [3,4], [5,6]]
copy_list_2d = copy.deepcopy(original_list_2d)
copy_list_2d[0] = 999
copy_list_2d[1][0] = -1
print(f"original: {original_list_2d}")
print(f"copy: {copy_list_2d}")
original: [[1, 2], [3, 4], [5, 6]]
copy: [999, [-1, 4], [5, 6]]
上記の様に、二次元配列の場合も、深いコピーの方ではcopy_listを編集したとしてもoriginal_listは変化しません。
まとめ
Pythonでオブジェクトをコピーする方法について、浅いコピーと深いコピーの2つがあります。オブジェクトの種類によって、それぞれのコピー方法が異なる動作をするため、適切に使い分ける必要があります。
関連検索ワード
How to use python “copy” function?
関連キーワード
python, 入門, 使い方, 初心者, コピー, copy, deepcopy