Python - copy と deepcopy と dict
投稿日: 2023/02/02
更新日: 2023/02/02
更新日: 2023/02/02
タグ:
python
概要
変数を他の変数にコピーする時に気をつけたいこと。
やってみた
import copy
# case1
a = {1: {10: 100, 20: 200}, 2: 20}
b = a.copy()
b[1][10] = 999
b[2] = 99
print(f"{a=} / {b=}")
# a={1: {10: 999, 20: 200}, 2: 20} / b={1: {10: 999, 20: 200}, 2: 99}
# case2
a = {1: {10: 100, 20: 200}, 2: 20}
b = copy.copy(a)
b[1][10] = 999
b[2] = 99
print(f"{a=} / {b=}")
# a={1: {10: 999, 20: 200}, 2: 20} / b={1: {10: 999, 20: 200}, 2: 99}
# case3
a = {1: {10: 100, 20: 200}, 2: 20}
b = copy.deepcopy(a)
b[1][10] = 999
b[2] = 99
print(f"{a=} / {b=}")
# a={1: {10: 100, 20: 200}, 2: 20} / b={1: {10: 999, 20: 200}, 2: 99}
# case4
a = {1: {10: 100, 20: 200}, 2: 20}
b = a
b[1][10] = 999
b[2] = 99
print(f"{a=} / {b=}")
# a={1: {10: 999, 20: 200}, 2: 99} / b={1: {10: 999, 20: 200}, 2: 99}
表1:コピー元(a)の変化について
case | 関数 | val (a[2]) |
dict のなかの val (a[1][10]) |
---|---|---|---|
1 | ビルトインメソッド | 変化なし | 変化あり |
2 | copy.copy() | 変化なし | 変化あり |
3 | copy.deepcopy() | 変化なし | 変化なし |
4 | 直接代入 | 変化あり |
変化あり |
考察
使用用途に応じて使い分ける必要がある。
今後とも dict の中に dict が入ってこない処理に関してはビルトインメソッドを使って良いだろう。しかし、どんな dict が入ってくるかわからない関数では最初から deepcopy を使っておくと安心である。
おまけ:keyだけコピーしたい場合
fromkeys
という便利なビルトインメソッドが存在する。
dict.fromkeys(a)
# {1: None, 2: None}
dict.fromkeys(a, None)
# {1: None, 2: None}
dict.fromkeys(a, 999)
# {1: 999, 2: 999}