【Python入門】Pythonのcopy関数とは?使い方と活用方法を徹底解説

Python

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