【Python】辞書の「参照共有」「浅いコピー」と「深いコピー」の違い

Pythonにおける辞書の「参照共有」「浅いコピー」と「深いコピー」の違いについて詳しく解説します。

辞書の「参照共有」「浅いコピー」と「深いコピー」

Pythonでは、辞書型のデータをコピーする方法が3つありますが、動作がまったく異なる**ので注意が必要です。

方法 コピーの種類 特徴
= で代入 参照共有(コピーではない) 元の辞書と同じものを指す
copy() メソッド 浅いコピー(shallow copy) 一階層目だけ複製、ネストされた辞書は共有される
copy.deepcopy() 関数 深いコピー(deep copy) 全階層を完全に複製、完全に独立した辞書になる

以下のコードは、 = で代入した場合(参照が共有される)の例です。

pikori_items = {
    "回復薬": 5,
    "装備": {
        "武器": "鉄の剣",
        "防具": "革の盾"
    }
}

# 持ち物を複製
copy_items = pikori_items

# 複製側を変更
copy_items["回復薬"] = 99

print("勇者ぴこりの持ち物:", pikori_items)
print("勇者ぴこりの持ち物のコピー:", copy_items)
勇者ぴこりの持ち物: {‘回復薬’: 99, ‘装備’: {‘武器’: ‘鉄の剣’, ‘防具’: ‘革の盾’}}
勇者ぴこりの持ち物のコピー: {‘回復薬’: 99, ‘装備’: {‘武器’: ‘鉄の剣’, ‘防具’: ‘革の盾’}}

= で代入すると、元の辞書と同じものを指す(両方が同じ辞書を共有)するため、コピー先の辞書を変更すると、コピー元の辞書も変わってしまいます。(回復薬が両方とも99になっている)
以下のコードは、 copy() を使って浅いコピーをする例です。

pikori_items = {
    "回復薬": 5,
    "装備": {
        "武器": "鉄の剣",
        "防具": "革の盾"
    }
}

# 持ち物を複製(浅いコピー)
copy_items = pikori_items.copy()

# 複製側を変更
copy_items["回復薬"] = 99
copy_items["装備"] ["武器"] = "鋼の剣"

print("勇者ぴこりの持ち物:", pikori_items)
print("勇者ぴこりの持ち物のコピー:", copy_items)
勇者ぴこりの持ち物: {‘回復薬’: 5, ‘装備’: {‘武器’: ‘鋼の剣’, ‘防具’: ‘革の盾’}}
勇者ぴこりの持ち物のコピー: {‘回復薬’: 99, ‘装備’: {‘武器’: ‘鋼の剣’, ‘防具’: ‘革の盾’}}

実行結果では、回復薬はコピーだけが99に変更されましたが、武器は両方とも「鋼の剣」に変わってしまっています。copy() メソッドは、一階層目だけ複製しますが、ネストされた辞書は共有されるためです。 ネストされた辞書も複製する場合、以下コードのように、copy.deepcopy()を使います。

import copy

pikori_items = {
    "回復薬": 5,
    "装備": {
        "武器": "鉄の剣",
        "防具": "革の盾"
    }
}

# 持ち物を複製(深いコピー)
copy_items = copy.deepcopy(pikori_items)

# 複製側を変更
copy_items["回復薬"] = 99
copy_items["装備"] ["武器"] = "鋼の剣"

print("勇者ぴこりの持ち物:", pikori_items)
print("勇者ぴこりの持ち物のコピー:", copy_items)

勇者ぴこりの持ち物: {‘回復薬’: 5, ‘装備’: {‘武器’: ‘鉄の剣’, ‘防具’: ‘革の盾’}}
勇者ぴこりの持ち物のコピー: {‘回復薬’: 99, ‘装備’: {‘武器’: ‘鋼の剣’, ‘防具’: ‘革の盾’}}

関連ページ(もっと学びたい人へ)

辞書型の使い方については、以下ページで詳しく学ぶことができます。

【Python】辞書型(連想配列)の使い方を徹底解説(試験対策問題あり)
Pythonの辞書型(連想配列)の使い方について入門者向けに解説します。

Pythonの基礎から応用例まで、以下ページから学ぶことができます。

【Python超入門】基礎から応用例まで幅広く解説
Pythonの使い方について、基礎文法から応用例まで入門者向けに解説します。
この記事を書いた人
西住技研

プログラミング言語「Python」を研究、仕事、趣味でデータ分析や作業自動化などに活用してきたノウハウを情報発信しています。
筆者の詳しいプロフィールやお問合せはこちらのページまで。
YoutubeX(旧Twitter)でも情報発信中です!

西住技研をフォローする
Python基礎

コメント