Python
python3

pythonの辞書のコピーを色々

pythonで辞書を一部再利用しようとした時に,deepcopyしようとしたんだけど,そこまでやる必要あったっけ?と思って簡単にテストした.

(追記)
そういえば速度テストをしてないことを思い出したので追記.

結論

辞書くらい参照の少ないオブジェクトのコピーごときにdeepcopyは要らない.
要素にクラスみたいなオブジェクトを入れてるなら別だが,文字列如きならやっぱし要らない.

(追記)
インポートするのは面倒だけど,実行速度的には
copy.copy <= dict(x.item()) < copy.deepcopy
可読性の面では,copyと書かれた方が分かりやすいかな…好みかもしれないが
さすがにdeepcopyは文字列でも遅かった

検証

In [1]: import copy

In [2]: a={1:'a',2:'b'}

In [3]: b=a;c=copy.copy(a);d=copy.deepcopy(a);e=dict(a.items())

In [4]: a
Out[4]: {1: 'a', 2: 'b'}

In [5]: b
Out[5]: {1: 'a', 2: 'b'}

In [6]: c
Out[6]: {1: 'a', 2: 'b'}

In [7]: d
Out[7]: {1: 'a', 2: 'b'}

In [8]: e
Out[8]: {1: 'a', 2: 'b'}

In [9]: a[3]='c'

In [10]: a
Out[10]: {1: 'a', 2: 'b', 3: 'c'}

In [11]: b
Out[11]: {1: 'a', 2: 'b', 3: 'c'}

In [12]: c
Out[12]: {1: 'a', 2: 'b'}

In [13]: d
Out[13]: {1: 'a', 2: 'b'}

In [14]: e
Out[14]: {1: 'a', 2: 'b'}

In [15]: a[2] += 'a'

In [16]: a
Out[16]: {1: 'a', 2: 'ba', 3: 'c'}

In [17]: b
Out[17]: {1: 'a', 2: 'ba', 3: 'c'}

In [18]: c
Out[18]: {1: 'a', 2: 'b'}

In [19]: d
Out[19]: {1: 'a', 2: 'b'}

In [20]: e
Out[20]: {1: 'a', 2: 'b'}

(追記)

In [1]: import copy

In [2]: x = {'a':'aaa', 'b':'bbb', 'c':'ccc','d':'ddd'}

In [3]: %timeit y = copy.copy(x)
        815 ns ± 12.6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [4]: %timeit y = dict(x.items())
        1.07 µs ± 2.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [5]: %timeit y = copy.deepcopy(x)
        9.85 µs ± 135 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)