Python copy()とdeepcopy()の違い|浅いコピー・深いコピーを解説

Pythonでは、リストや辞書などのオブジェクトをコピーするときに、copy()やdeepcopy()を使用できます。
特に注意したいのが、copy()は「浅いコピー」、deepcopy()は「深いコピー」であるという違いです。
この記事では、Pythonのcopy()とdeepcopy()について、サンプルコードを使ってわかりやすく解説します。
Pythonのcopy()とdeepcopy()とは?
copy()とdeepcopy()は、Pythonのcopyモジュールで提供されているコピー用の関数です。
基本的な使い方は次のとおりです。
import copy
a = [1, 2, 3]
b = copy.copy(a)
c = copy.deepcopy(a)
copy.copy()は浅いコピーを作成し、copy.deepcopy()は深いコピーを作成します。
| 関数 | 意味 |
|---|---|
copy.copy() |
浅いコピー |
copy.deepcopy() |
深いコピー |
copy()は浅いコピー
copy.copy()は、元のオブジェクトを浅くコピーします。
例えば、リストをコピーしてみましょう。
import copy
a = [1, 2, 3]
b = copy.copy(a)
b[0] = 100
print(a)
print(b)
実行結果は次のようになります。
[1, 2, 3]
[100, 2, 3]
この場合、aとbは別のリストなので、bを変更してもaは変わりません。
copy()では入れ子になったオブジェクトに注意
copy()を使うときに注意したいのが、リストなどの中に別のリストが入っている場合です。
import copy
a = [[1, 2], [3, 4]]
b = copy.copy(a)
b[0][0] = 100
print(a)
print(b)
実行結果は次のようになります。
[[100, 2], [3, 4]]
[[100, 2], [3, 4]]
一見すると、bだけを変更したように見えます。
しかし、aの中身まで変更されています。
これは、copy()が外側のリストだけをコピーし、内側のリストまではコピーしないためです。
deepcopy()は深いコピー
deepcopy()は、入れ子になったオブジェクトも含めてコピーします。
import copy
a = [[1, 2], [3, 4]]
b = copy.deepcopy(a)
b[0][0] = 100
print(a)
print(b)
実行結果は次のようになります。
[[1, 2], [3, 4]]
[[100, 2], [3, 4]]
今度は、bの中のリストを変更しても、aは変更されません。
これが、浅いコピーと深いコピーの大きな違いです。
copy()とdeepcopy()の違い
最も重要な違いを表にすると次のようになります。
copy() |
deepcopy() |
|
|---|---|---|
| コピーの種類 | 浅いコピー | 深いコピー |
| 外側のオブジェクト | コピーする | コピーする |
| 入れ子のオブジェクト | 基本的に共有される | コピーされる |
| 処理速度 | 比較的速い | 比較的遅い |
copy()とdeepcopy()の違いを確認する
オブジェクトが同じものを参照しているかどうかは、is演算子で確認できます。
import copy
a = [[1, 2], [3, 4]]
b = copy.copy(a)
c = copy.deepcopy(a)
print(a is b)
print(a is c)
print(a[0] is b[0])
print(a[0] is c[0])
実行結果は次のようになります。
False
False
True
False
copy()では、外側のリストは別物になりますが、中に入っているリストは同じオブジェクトを参照しています。
一方、deepcopy()では、内側のリストも別のオブジェクトとしてコピーされます。
リストのcopy()メソッドとの違い
Pythonのリストには、copy()というメソッドもあります。
a = [1, 2, 3]
b = a.copy()
このlist.copy()は、copy.copy()と同じように浅いコピーを作成します。
例えば次のコードです。
a = [[1, 2], [3, 4]]
b = a.copy()
b[0][0] = 100
print(a)
実行結果は次のようになります。
[[100, 2], [3, 4]]
入れ子になったリストまで完全に独立させたい場合は、deepcopy()を使用します。
import copy
a = [[1, 2], [3, 4]]
b = copy.deepcopy(a)
b[0][0] = 100
print(a)
実行結果は次のようになります。
[[1, 2], [3, 4]]
copy.copy()と代入は違う
コピーについて理解するときは、単純な代入との違いも重要です。
a = [1, 2, 3]
b = a
b[0] = 100
print(a)
print(b)
実行結果は次のようになります。
[100, 2, 3]
[100, 2, 3]
これは、b = aではリストそのものをコピーしていないためです。
aとbが同じリストを参照しています。
一方、copy.copy()を使うと外側のオブジェクトがコピーされます。
import copy
a = [1, 2, 3]
b = copy.copy(a)
b[0] = 100
print(a)
print(b)
実行結果は次のようになります。
[1, 2, 3]
[100, 2, 3]
スライスによるコピーとの違い
リストでは、スライスを使ってコピーする方法もあります。
a = [1, 2, 3]
b = a[:]
この方法も、基本的には浅いコピーです。
そのため、入れ子になったリストでは次のような問題が起こります。
a = [[1, 2], [3, 4]]
b = a[:]
b[0][0] = 100
print(a)
実行結果は次のようになります。
[[100, 2], [3, 4]]
内側のリストまでコピーしたい場合は、deepcopy()を使用します。
deepcopy()を使う場面
deepcopy()は、元のデータとコピーしたデータを完全に独立させたい場合に便利です。
例えば、設定データの複製などに利用できます。
import copy
config = {
"user": {
"name": "Taro",
"age": 20
},
"options": {
"debug": True
}
}
new_config = copy.deepcopy(config)
new_config["user"]["age"] = 30
print(config["user"]["age"])
print(new_config["user"]["age"])
実行結果は次のようになります。
20
30
元のconfigを変更せずに、コピーしたデータだけを変更できます。
deepcopy()を使えば常に良いわけではない
深いコピーは便利ですが、必要のない場面でdeepcopy()を使う必要はありません。
浅いコピーで十分な場合は、copy()やリストのcopy()メソッドなどを使ったほうが処理が軽くなります。
例えば、単純な1階層のリストであれば、次のようなコピーで十分です。
a = [1, 2, 3]
b = a.copy()
一方、複雑な入れ子構造を独立させたい場合には、deepcopy()が候補になります。
元の変数まで変わってしまうときは
代入やコピーのあとに元のデータまで変わってしまう原因と対策は、次の記事で症状別にまとめています。
Pythonのcopy()とdeepcopy()まとめ
Pythonのcopy()とdeepcopy()の違いを理解するポイントは、「入れ子になったオブジェクトまでコピーするか」です。
copy.copy()は浅いコピーcopy.deepcopy()は深いコピー- 浅いコピーでは、入れ子のオブジェクトが共有されることがある
- 深いコピーでは、入れ子のオブジェクトもコピーされる
- リストの
copy()メソッドも浅いコピー b = aはコピーではなく同じオブジェクトへの代入
特に、リストや辞書が入れ子になっている場合は、copy()とdeepcopy()の違いを意識することが重要です。
「コピーしたはずなのに元のデータまで変わってしまった」という問題は、浅いコピーとオブジェクト参照の仕組みを理解すると原因を把握しやすくなります。
あわせて読みたい
copy()は、Pythonのリスト(list)・辞書(dict)・集合(set)で使えるメソッドです。ほかの関数・メソッドとあわせて確認したい方は、次の一覧ページをご覧ください。
- Python リスト(list)メソッド一覧|使い方・サンプルコードを初心者向けに解説
- Python 辞書(dict)メソッド一覧|使い方を初心者向けに解説
- Python 集合(set)メソッド一覧|使い方・サンプルコードを初心者向けに解説
- Python基本関数・メソッド完全一覧|初心者が覚えておきたい関数・文字列・リスト・辞書・ファイル操作
- Python weakrefとは?弱参照でメモリを節約する方法
詳しくはPython copy()とは?リストや辞書をコピーする方法を初心者向けに解説で解説しています。







