読者です 読者をやめる 読者になる 読者になる

<Python> 参照とコピー

いまさらながら、
参照referenceとコピーcopyを勉強した。

=は参照。
なので、

In [59]: lst = [1, 2, 3]

In [60]: lst2 = lst

In [61]: lst2[2] = 20

In [62]: lst2
Out[62]: [1, 2, 20]

In [63]: lst
Out[63]: [1, 2, 20]

と、いうように、lst2lstと同じものを指している。
id()でみると、

In [64]: id(lst)
Out[64]: 188099976

In [65]: id(lst2)
Out[65]: 188099976

同じ。
で、コピーcopyするには、
リストの場合、[:]する。

In [66]: lst2 = lst[:]

In [69]: lst2[2] = 50

In [70]: lst
Out[70]: [1, 2, 20]

In [71]: lst2
Out[71]: [1, 2, 50]

ね。なるほど。

で、オブジェクトのリスト場合。

In [73]: class c():
    ...:     x = 1
    ...:     

In [74]: x = c()

In [75]: y = c()

In [76]: z = c()

In [77]: lst = [x, y, z]

In [78]: lst
Out[78]: 
[<__main__.c at 0xb338780>,
 <__main__.c at 0xb338438>,
 <__main__.c at 0xb338f60>]

In [79]: lst2 = lst[:]

In [80]: lst2
Out[80]: 
[<__main__.c at 0xb338780>,
 <__main__.c at 0xb338438>,
 <__main__.c at 0xb338f60>]

と、いうことで、同じオブジェクトを参照している。
オブジェクトごとコピーするには、モジュールcopy.deepcopy()を使う。

In [81]: import copy

In [82]: lst2 = copy.deepcopy(lst)

In [83]: lst2
Out[83]: 
[<__main__.c at 0xb3399e8>,
 <__main__.c at 0xb339518>,
 <__main__.c at 0xb3396d8>]

参考。

Pythonの浅いコピー、深いコピー – HimaJew Blog

マニュアル。

8.10. copy — 浅いコピーおよび深いコピー操作 — Python 3.5.1 ドキュメント