Pythonの辞書をコピーする方法!浅いコピーと深いコピーの違いを解説
生徒
「Pythonの辞書をコピーしたいんですが、どうすればいいですか?」
先生
「辞書をコピーするにはいくつか方法がありますよ。単純なコピーだけでなく、“浅いコピー”と“深いコピー”の違いも理解するのが大切です。」
生徒
「浅いコピーと深いコピー?どういう意味ですか?」
先生
「では、例を使いながらやさしく説明していきましょう。」
1. Pythonの辞書をコピーする基本
Pythonの辞書は、dictというデータ型で「キー」と「値」のペアを保存します。コピーとは、ある辞書の内容を別の辞書に複製する操作です。たとえば以下のようにコピーできます。
original = {"名前": "太郎", "年齢": 25}
copied = original.copy()
print(copied)
この方法は「浅いコピー」と呼ばれます。次の章で詳しく説明します。
2. 辞書を=で代入するのはコピーではない?
よくやりがちな間違いは、=を使ってコピーしようとすることです。実はこれはコピーではなく「同じ辞書を指す別名を作っている」だけです。
original = {"名前": "太郎"}
copy_like = original
copy_like["名前"] = "花子"
print(original)
{'名前': '花子'}
このように、元の辞書originalまで変わってしまいます。
3. 浅いコピー(shallow copy)とは?
浅いコピーは、辞書の最上位のデータだけをコピーします。辞書の中にリストや他の辞書などの「入れ子(ネスト)」がある場合、それらの中身まではコピーされません。
original = {"名前": "太郎", "趣味": ["読書", "散歩"]}
copied = original.copy()
copied["趣味"].append("料理")
print(original)
{'名前': '太郎', '趣味': ['読書', '散歩', '料理']}
「趣味」のリストが元の辞書にも影響してしまうのがポイントです。
4. 深いコピー(deep copy)とは?
深いコピーは、辞書の中にあるリストや他の辞書まで完全にコピーします。つまり、すべて別物になるので、元のデータには影響しません。深いコピーを使うにはcopyモジュールのdeepcopy()関数を使います。
import copy
original = {"名前": "太郎", "趣味": ["読書", "散歩"]}
deep_copied = copy.deepcopy(original)
deep_copied["趣味"].append("料理")
print(original)
{'名前': '太郎', '趣味': ['読書', '散歩']}
このように、originalはまったく変化していません。
5. copy()とdeepcopy()の使い分け
どちらを使うかは、辞書の中にリストや辞書などの「複雑なデータ構造」があるかどうかで決めましょう。
- 辞書の中身が文字列や数字だけなら
copy()でOK - 辞書の中にリスト・辞書・オブジェクトがあるなら
deepcopy()を使う
6. 辞書をdict()でコピーする方法
実は、dict()関数を使っても浅いコピーができます。
original = {"名前": "太郎", "年齢": 25}
copied = dict(original)
print(copied)
copy()メソッドと同じような動作をします。
7. 辞書のコピー時に気をつけたいポイント
=ではコピーにならない(ただの参照)- 浅いコピーはネストされた中身は同じものを指す
- 深いコピーは完全に別のコピーになる
- どちらを使うかはデータの構造で選ぶ
まとめ
Pythonの辞書コピーを正しく理解することの大切さ
今回の記事では、Pythonの辞書をコピーする方法について、「コピーとは何か」という基本的な考え方から、浅いコピーと深いコピーの違いまでを丁寧に確認してきました。辞書はPythonの中でも非常によく使われるデータ型であり、データを安全に扱うためにはコピーの仕組みを理解しておくことが欠かせません。特に初心者のうちは、見た目が同じでも「中身が本当に別物なのかどうか」を意識せずに使ってしまい、思わぬバグにつながるケースが多くあります。
辞書のコピーは、一見すると簡単な操作に見えますが、実際には「どこまで複製されるのか」という点がとても重要です。単純に内容を複製したつもりでも、内部にリストや別の辞書が含まれている場合、それらが共有されたままになっていると、後からデータを変更したときに元の辞書まで変わってしまうことがあります。こうした挙動を理解せずに使うと、「なぜ元のデータが変わったのか分からない」という状態になりやすいため、基礎の段階でしっかり押さえておきたいポイントです。
代入とコピーの違いをはっきり区別しよう
記事の中でも触れた通り、イコール記号を使った代入はコピーではありません。これはPythonに限らず、多くのプログラミング言語で共通する考え方ですが、代入は「同じデータを指す別の名前を付けている」だけの状態です。そのため、一方を変更すると、もう一方にも影響が出ます。この挙動を知らないまま辞書を扱うと、意図せずデータが書き換わってしまい、原因の特定が難しくなります。
一方で、copyメソッドやdict関数を使ったコピーは、新しい辞書を作成します。ただし、この時点ではまだ浅いコピーであり、辞書の最上位の構造だけが複製されている状態です。中に入っているリストや辞書は、元のものと同じ参照を持っている点に注意が必要です。この違いを理解しているかどうかで、プログラムの安全性は大きく変わります。
浅いコピーと深いコピーの使い分けがポイント
浅いコピーは、辞書の中身が文字列や数値などの単純なデータだけで構成されている場合には、十分に実用的です。処理も軽く、コードもシンプルに書けるため、多くの場面で活躍します。しかし、辞書の中にリストや別の辞書が含まれている場合は、浅いコピーでは不十分になることがあります。
そのような場合に役立つのが深いコピーです。deepcopyを使えば、辞書の中に含まれるすべてのデータ構造を再帰的にコピーし、完全に独立した別の辞書を作成できます。これにより、コピー後のデータを自由に変更しても、元の辞書には一切影響が出ません。設定情報やテンプレートデータ、元の状態を保持しておきたいデータを扱う場面では、深いコピーが非常に重要な役割を果たします。
サンプルプログラムでコピーの挙動を確認
import copy
profile = {
"名前": "太郎",
"スキル": ["Python", "HTML"]
}
# 浅いコピー
shallow = profile.copy()
shallow["スキル"].append("CSS")
# 深いコピー
deep = copy.deepcopy(profile)
deep["スキル"].append("JavaScript")
print(profile)
print(shallow)
print(deep)
この例では、浅いコピーでは元の辞書とリストが共有されているため、変更が影響します。一方、深いコピーでは完全に別のデータとして扱われるため、元の辞書はそのまま保たれます。実際に手を動かして結果を確認することで、コピーの違いがよりはっきり理解できるでしょう。
辞書コピーを理解すると安全なコードが書ける
辞書のコピーを正しく使い分けられるようになると、データの扱いが一段と安全になります。特に複数の処理で同じデータを扱う場合や、一時的な加工を行いたい場合には、「元のデータを守る」という意識がとても重要です。コピーの仕組みを理解していれば、意図しない変更を防ぎ、安心してプログラムを組み立てられるようになります。
生徒「最初はコピーって全部同じだと思っていましたが、浅いコピーと深いコピーで全然違うんですね。」
先生「そうだね。特に辞書の中にリストが入っている場合は、その違いがはっきり出るよ。」
生徒「イコールで代入するとコピーにならないのも、ちょっと驚きました。」
先生「そこに気づけたのは大きな一歩だよ。代入とコピーの違いは、Pythonを使う上でとても大切なんだ。」
生徒「これからは、データの中身を見て、copyかdeepcopyかを選ぶようにします。」
先生「その意識があれば安心だね。辞書のコピーを理解できれば、より安全で読みやすいコードが書けるようになるよ。」