【Python】直接代入/シャローコピー/ディープコピーの違い
更新月:2024/12
Pythonの変数への代入における、直接代入/シャローコピー/ディープコピーの違いについて理解する記事になります。
シャローコピーとディープコピーの違い
1. 直接代入するケース
original_list = [1, 2, [3, 4]] # 直接代入 assigned_list = original_list # 変更 assigned_list[0] = 99 assigned_list[2][0] = 999 # 結果を表示 print("original_list:", original_list) # [99, 2, [999, 4]] print("assigned_list:", assigned_list) # [99, 2, [999, 4]]
説明:
- 「
assigned_list = original_list
」とした時点で、assigned_list
とoriginal_list
は同じオブジェクトを指し示します。 - そのため、
assigned_list
で変更を加えると、original_list
も影響を受けます。 - 特に、内側のリスト(
[3, 4]
)も両方で共有されているため、assigned_list[2][0] = 999
を変更したとき、original_list
も変更されます。
2. シャローコピーを用いるケース
import copy original_list = [1, 2, [3, 4]] # シャローコピーを作成 shallow_copy = original_list.copy() # 変更 shallow_copy[0] = 99 shallow_copy[2][0] = 999 # 結果を表示 print("original_list:", original_list) # [1, 2, [999, 4]] print("shallow_copy:", shallow_copy) # [99, 2, [999, 4]]
説明:
shallow_copy = original_list.copy()
で、シャローコピーを作成します。- シャローコピーでは、リストの要素(
1
,2
,[3, 4]
)がコピーされますが、内側のリスト([3, 4]
)の参照は共有されます。 - そのため、
shallow_copy[2][0] = 999
を変更すると、original_list
の中の内側のリストも影響を受けます。 - しかし、リストの最初の要素
0
を変更しても、original_list[0]
は変わりません。
3. ディープコピーを用いるケース
import copy original_list = [1, 2, [3, 4]] # ディープコピーを作成 deep_copy = copy.deepcopy(original_list) # 変更 deep_copy[0] = 99 deep_copy[2][0] = 999 # 結果を表示 print("original_list:", original_list) # [1, 2, [3, 4]] print("deep_copy:", deep_copy) # [99, 2, [999, 4]]
説明:
deep_copy = copy.deepcopy(original_list)
で、ディープコピーを作成します。- ディープコピーでは、元のリストとその中のオブジェクトをすべて新しくコピーします。
- そのため、元のリストとディープコピーはまったく独立したオブジェクトになります。
- したがって、
deep_copy[0] = 99
やdeep_copy[2][0] = 999
を変更しても、元のリストには影響を与えません。
まとめ:直接代入、シャローコピー、ディープコピーの違い
操作 | 直接代入 | シャローコピー | ディープコピー |
---|---|---|---|
変数間の関係 | 同じオブジェクトを参照 | 新しいリストオブジェクトが作成され、内部の参照は共有 | 新しいリストとその中身(再帰的に)もすべて新しくコピー |
内部オブジェクト(リスト等)の影響 | 変更が両方に影響を与える | 内部オブジェクトは参照を共有、変更が影響を与える | 完全に独立、変更が元のオブジェクトに影響しない |
変更時の挙動 | 両方に反映される | ミュータブルな内部オブジェクトに変更が反映される | 完全に独立しているので、元のオブジェクトに影響を与えない |
直感的な理解のためのポイント
- 直接代入では、2つの変数が同じオブジェクトを指し示しているため、どちらを変更しても両方に影響があります。
- シャローコピーでは、リスト自体のコピーは作成されますが、その中のミュータブルなオブジェクト(例えば、リストや辞書など)は参照が共有されるため、内部のオブジェクトの変更は元のリストにも影響を与えます。
- ディープコピーでは、オブジェクトとその中身が全て新しくコピーされるため、元のオブジェクトとディープコピーは完全に独立しています。
補足:シャローコピー&イミュータブルで影響を与えない理由
シャローコピーしたリストで数値や文字列のようなイミュータブルなオブジェクトを示す要素の内容を変更(直接代入)してもコピー元には影響を与えません。コピー先の要素として持つ参照値を別で作られた新規イミュータブルオブジェクトの参照値に書き換えるに過ぎないためです。
関連記事
外部リンク
生成AIメモ
- 利用AI:ChatGPT 4o mini、一部利用
- プロンプト1:pythonの「シャローコピー」の説明を初学者に向けた内容でお願いします。「参照値の値渡し」を内容に含めて、文を組み立ててほしいです。
- プロンプト2:説明をまとめて欲しいです。
・コピーメソッドを使わず、直接代入するケース
・シャローコピーを用いるケース
・ディープコピーを用いるケース
差が明確になる直感的にわかりやすい記述でお願いします。 - プロンプト3:先程の内容をhtml形式(style使用せず)で出力してほしいです。
内容チェック済。