1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Python初心者】copyモジュールまとめ(浅いコピーとdeepcopyの違い)

Posted at

copy モジュールによるオブジェクトの複製方法を整理しました。
特に copy()(浅いコピー)と deepcopy()(完全コピー)の違いは、試験でも実務でも重要です。

なぜコピーが必要?

Python ではオブジェクトを代入すると「同じものを共有」することになります。

a = [1, 2, 3]
b = a
b[0] = 999

print(a)  # [999, 2, 3] ← aも変わってしまう!
  • b = a は「aをコピー」しているのではなく、「aへの参照を代入」しています
  • そのため b を変更すると a も変わってしまいます

このようなケースで「コピーして別物として扱いたい」ときに、copy モジュールが登場します。

copy.copy():浅いコピー(shallow copy)

浅いコピーでは、最上位のオブジェクトだけがコピーされます。
その中にリストや辞書などの入れ子構造があると、それらは共有されます

import copy

original = [[1, 2], [3, 4]]
shallow = copy.copy(original)

shallow[0][0] = 999
print(original)  # [[999, 2], [3, 4]]
  • originalshallow は別のリストオブジェクト
  • ただし、中のリスト([1, 2] など)は同じものを指している

🔍 「じゃあ代入と変わらなくない?」と感じた方へ

実はこの疑問、とても本質的です。
中の要素が共有されるせいで「代入と変わらないのでは?」と思えてしまうのは自然なことです。

でも、外側のリスト自体は完全に別物であるという点が決定的に異なります。

import copy

a = [[1, 2], [3, 4]]
b = a            # 代入
c = copy.copy(a) # 浅いコピー

b.append([5, 6])
c.append([7, 8])

print("a:", a)  # [[1, 2], [3, 4], [5, 6]]
print("b:", b)  # [[1, 2], [3, 4], [5, 6]]
print("c:", c)  # [[1, 2], [3, 4], [7, 8]]
  • ba に完全に追従している(代入)
  • ca のコピーなので、別のリストとして .append() ができる

つまり、浅いコピーは:

  • 外側の構造をコピーして独立させたいとき
  • でも内側のデータ(ネスト)は変更しない前提

という場面で有効です。

copy.deepcopy():完全コピー(deep copy)

deepcopy() は、中の要素も含めてすべて再帰的にコピーします。

import copy

original = [[1, 2], [3, 4]]
deep = copy.deepcopy(original)

deep[0][0] = 999
print(original)  # [[1, 2], [3, 4]] ← 元のデータは影響を受けない
  • deep の中にあるリストも original とは完全に別物になります
  • そのため、変更が元に影響しません

copy.copy() と代入と deepcopy の違いまとめ

操作内容 リスト本体 内部要素(入れ子)
=(代入) 同じ 同じ
copy.copy() 同じ
copy.deepcopy()

いつ使い分ける?

  • 入れ子構造がない場合copy.copy() でも OK
  • 外側だけ分離したい(中身は共有OK)copy.copy()
  • 元データと完全に独立させたいcopy.deepcopy()

おわりに

今回は copy モジュールによるオブジェクトのコピー方法をまとめました。
特に copy() は見た目はコピーっぽく見えても中身が共有されてしまう点に注意が必要です。

最初は「なんで元まで変わるの?」と混乱しましたが、copy() は表面だけをコピーし、deepcopy() は中身まで完全にコピーしてくれると覚えると分かりやすかったです。

また、「浅いコピーって代入と何が違うの?」と疑問に思ったのですが、外側のオブジェクトだけが独立していて、中身は共有されるという仕組みを理解することで納得感が得られました。
この違いを意識することで、どんな場面で copy() を使うべきかがだんだん見えてきたように思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?