Pythonのlist,numpyで、1次元,多次元で、代入,スライス,copy,deepcopyとかしてみた。一部np.shares_memoryで確認

#目的
いわゆる、shallow-copyとかdeep-copyに関するもの。
表題のことを30ケースほど試してみた。
結果は、以下に示すとおり(Python 3.7.2)。
比較的複雑なので、実現したい目的に応じて、その目的の観点にまとを絞って
方法を検討するのがいいと思いました。
（目的の例：計算時間都合？で、できるだけ、実際のCOPYを少なくしたい　等）
どういう動きになるのか、汎用的に頭に入れるのはやや困難？（ワタシのレベルでは）

#結果に対するコメント

**listとnumpyでは、違う。**
**1次元と2次元では、違う。**
**.deepcopy()は、わかり易いと感じた。**
※np.shares_memoryは、期待の動きと違う。

###「listとnumpyでは、違う。」の例
【A3】と【A13】の比較でわかるように、
listのスライスは、copyになっているが、
ndarrayのスライスは。参照になっている。
（どこかで、実行速度のため、コピーを避けている的な説明を見たことがあるが、それにしては、ndarrayもその他の条件であっさりコピーしていたり
するので、理由はよくわからない。）

```
>>> #【A3】1次元,list,スライス
...
>>> a = [1,2,3,4]
>>> b = a[:]
>>> a[0] = 900
>>> a[1] = 99911
>>> a
[900, 99911, 3, 4]
>>> b
[1, 2, 3, 4]
```

```
>>> #【A13】1次元,ndarray,スライス
...
>>> a = np.array([1,2,3,4])
>>> b = a[:]
>>> a[0] = 900
>>> a[1] = 99911
>>> a
array([  900, 99911,     3,     4])
>>> b
array([  900, 99911,     3,     4])
>>> np.shares_memory(a,b)
True

```

###
上に示した【A3】と以下の【A4】をの比較すると、
違っている。
ここで、**【A4】は、何もコピーされていないように見えるが、
topレベルはコピーされていることを
【A4_b】に示す。**

　Python Pocket Referenceの説明がわかりやすい。
（出典：　　Python Pocket Reference, 5th Edition 
　Python In Your Pocket
　By Mark Lutz 
　Publisher: O'Reilly Media）
>L.copy()
Make a top-level(shallow)copy of L. ...

```
>>> #【A4】2次元,list,スライス
...
>>> a = [[1,2],[3,4]]
>>> b = a[:][:]
>>> a[0][0] = 900
>>> a[1][1] = 99911
>>> a
[[900, 2], [3, 99911]]
>>> b
[[900, 2], [3, 99911]]
>>>

```

```
>>> #【A4_b】2次元,list,スライス
...
>>> a = [[1,2],[3,4]]
>>> b = a[:][:]
>>> a[0] = [900,9000]#変更
>>>        #（topレベルは、コピーされていることを示すため）
... a[1][1] = 99911
>>> a
[[900, 9000], [3, 99911]]
>>> b
[[1, 2], [3, 99911]]
>>>

```


#実行結果

```python
>>> import numpy as np
>>> import copy
>>>
>>>
```

#【A1】1次元,list,代入

```python
>>> a = [1,2,3,4]
>>> b = a # 代入では
>>> a[0] = 900
>>> a[1] = 99911
>>> a # a が変われば
[900, 99911, 3, 4]
>>> b # b も変わる
[900, 99911, 3, 4]
```

#【A2】2次元,list,代入
```py
>>> a = [[1,2],[3,4]]
>>> b = a # 代入では
>>> a[0][0] = 900
>>> a[1][1] = 99911
>>> a # a が変われば
[[900, 2], [3, 99911]]
>>> b # b も変わる
[[900, 2], [3, 99911]]
```

#【A3】1次元,list,スライス


```py
>>> a = [1,2,3,4]
>>> b = a[:] # 1次元スライスでの全代入は
>>> a[0] = 900
>>> a[1] = 99911
>>> a # a が変わっても
[900, 99911, 3, 4]
>>> b # b は変わらない
[1, 2, 3, 4]
```

#【A4】2次元,list,スライス

```py
>>> a = [[1,2],[3,4]]
>>> b = a[:][:]  # 2次元スライスでの全代入は
>>> a[0][0] = 900
>>> a[1][1] = 99911
>>> a # a が変われば
[[900, 2], [3, 99911]]
>>> b # b も変わる
[[900, 2], [3, 99911]]
```

#【A5】1次元,list,listのcopy関数

```py
>>> a = [1,2,3,4]
>>> b = a.copy() # 1次元の.copy() では
>>> a[0] = 900
>>> a[1] = 99911
>>> a # a が変わっても
[900, 99911, 3, 4]
>>> b # b は変わらない
[1, 2, 3, 4]
```

#【A6】2次元,list,listのcopy関数

```py
>>> a = [[1,2],[3,4]]
>>> b = a.copy() # 2次元の.copy() では
>>> a[0][0] = 900
>>> a[1][1] = 99911
>>> a # a が変われば
[[900, 2], [3, 99911]]
>>> b # b も変わる
[[900, 2], [3, 99911]]
```

#【A7】1次元,list,copyモジュールのcopy関数

```py
>>> a = [1,2,3,4]
>>> b = copy.copy(a) # copy.copy(1次元) では
>>> a[0] = 900
>>> a[1] = 99911
>>> a # a が変わっても
[900, 99911, 3, 4]
>>> b # b は変わらない
[1, 2, 3, 4]
```
#【A8】2次元,list,copyモジュールのcopy関数
```py
>>> a = [[1,2],[3,4]]
>>> b = copy.copy(a) # copy.copy(2次元) では
>>> a[0][0] = 900
>>> a[1][1] = 99911
>>> a # a が変わると
[[900, 2], [3, 99911]]
>>> b # b も変わる
[[900, 2], [3, 99911]]
```

#【A9】1次元,list,copyモジュールのdeepcopy関数
```py
>>> a = [1,2,3,4]
>>> b = copy.deepcopy(a)
>>> a[0] = 900
>>> a[1] = 99911
>>> a
[900, 99911, 3, 4]
>>> b
[1, 2, 3, 4]
```
#【A10】2次元,list,copyモジュールのdeepcopy関数
```py
>>> a = [[1,2],[3,4]]
>>> b = copy.deepcopy(a)
>>> a[0][0] = 900
>>> a[1][1] = 99911
>>> a
[[900, 2], [3, 99911]]
>>> b
[[1, 2], [3, 4]]
```
#【A11】1次元,ndarray,代入
```py
>>> a = np.array([1,2,3,4])
>>> b = a
>>> a[0] = 900
>>> a[1] = 99911
>>> a
array([  900, 99911,     3,     4])
>>> b
array([  900, 99911,     3,     4])
>>> np.shares_memory(a,b)
True
```
#【A12】2次元,ndarray,代入
```py
>>> a = np.array([[1,2],[3,4]])
>>> b = a
>>> a[0][0] = 900
>>> a[1][1] = 99911
>>> a
array([[  900,     2],
       [    3, 99911]])
>>> b
array([[  900,     2],
       [    3, 99911]])
>>> np.shares_memory(a,b)
True
```
#【A13】1次元,ndarray,スライス
```py
>>> a = np.array([1,2,3,4])
>>> b = a[:]
>>> a[0] = 900
>>> a[1] = 99911
>>> a
array([  900, 99911,     3,     4])
>>> b
array([  900, 99911,     3,     4])
>>> np.shares_memory(a,b)
True
```
#【A14】2次元,ndarray,スライス
```py
>>> a = np.array([[1,2],[3,4]])
>>> b = a[:][:]
>>> a[0][0] = 900
>>> a[1][1] = 99911
>>> a
array([[  900,     2],
       [    3, 99911]])
>>> b
array([[  900,     2],
       [    3, 99911]])
>>> np.shares_memory(a,b)
True
```
#【A15】1次元,ndarray,numpyのcopy関数
```py
>>> a = np.array([1,2,3,4])
>>> b = a.copy()
>>> a[0] = 900
>>> a[1] = 99911
>>> a
array([  900, 99911,     3,     4])
>>> b
array([1, 2, 3, 4])
>>> np.shares_memory(a,b)
False
```
#【A16】2次元,ndarray,numpyのcopy関数
```py
>>> a = np.array([[1,2],[3,4]])
>>> b = a.copy()
>>> a[0][0] = 900
>>> a[1][1] = 99911
>>> a
array([[  900,     2],
       [    3, 99911]])
>>> b
array([[1, 2],
       [3, 4]])
>>> np.shares_memory(a,b)
False
```
#【A17】1次元,ndarray,copyモジュールのcopy関数
```py
>>> a = np.array([1,2,3,4])
>>> b = copy.copy(a)
>>> a[0] = 900
>>> a[1] = 99911
>>> a
array([  900, 99911,     3,     4])
>>> b
array([1, 2, 3, 4])
>>> np.shares_memory(a,b)
False
```
#【A18】2次元,ndarray,copyモジュールのcopy関数
```py
>>> a = np.array([[1,2],[3,4]])
>>> b = copy.copy(a)
>>> a[0][0] = 900
>>> a[1][1] = 99911
>>> a
array([[  900,     2],
       [    3, 99911]])
>>> b
array([[1, 2],
       [3, 4]])
>>> np.shares_memory(a,b)
False
```
#【A19】1次元,ndarray,copyモジュールのdeepcopy関数
```py
>>> a = np.array([1,2,3,4])
>>> b = copy.deepcopy(a)
>>> a[0] = 900
>>> a[1] = 99911
>>> a
array([  900, 99911,     3,     4])
>>> b
array([1, 2, 3, 4])
>>> np.shares_memory(a,b)
False
```
#【A20】2次元,ndarray,copyモジュールのdeepcopy関数
```py
>>> a = np.array([[1,2],[3,4]])
>>> b = copy.deepcopy(a)
>>> a[0][0] = 900
>>> a[1][1] = 99911
>>> a
array([[  900,     2],
       [    3, 99911]])
>>> b
array([[1, 2],
       [3, 4]])
>>> np.shares_memory(a,b)
False
```

```python
>>> import numpy as np
>>> import copy
```

#【B1】2次元,list,代入
```py
>>> ee = [1,2]
>>> ff = [3,4]
>>> gg = [100,200]
>>>
>>> a = [ee,ff]
>>> b = a
>>> a[1] = gg
>>> ee[1] = 99911
>>> a
[[1, 99911], [100, 200]]
>>> b
[[1, 99911], [100, 200]]
```
#【B2】2次元,list,スライス
```py
>>> ee = [1,2]
>>> ff = [3,4]
>>> gg = [100,200]
>>>
>>> a = [ee,ff]
>>> b = a[:][:]
>>> a[1] = gg
>>> ee[1] = 99911
>>> a
[[1, 99911], [100, 200]]
>>> b
[[1, 99911], [3, 4]]
```
#【B3】2次元,list,listのcopy関数
```py
>>> ee = [1,2]
>>> ff = [3,4]
>>> gg = [100,200]
>>>
>>> a = [ee,ff]
>>> b = a.copy()
>>> a[1] = gg
>>> ee[1] = 99911
>>> a
[[1, 99911], [100, 200]]
>>> b
[[1, 99911], [3, 4]]
```
#【B4】2次元,list,copyモジュールのcopy関数
```py
>>> ee = [1,2]
>>> ff = [3,4]
>>> gg = [100,200]
>>>
>>> a = [ee,ff]
>>> b = copy.copy(a)
>>> a[1] = gg
>>> ee[1] = 99911
>>> a
[[1, 99911], [100, 200]]
>>> b
[[1, 99911], [3, 4]]
```
#【B5】2次元,list,copyモジュールのdeepcopy関数
```py
>>> ee = [1,2]
>>> ff = [3,4]
>>> gg = [100,200]
>>>
>>> a = [ee,ff]
>>> b = copy.deepcopy(a)
>>> a[1] = gg
>>> ee[1] = 99911
>>> a
[[1, 99911], [100, 200]]
>>> b
[[1, 2], [3, 4]]
```
#【B6】2次元,ndarray,代入
```py
>>> ee = np.array([1,2])
>>> ff = np.array([3,4])
>>> gg = np.array([100,200])
>>>
>>> a = np.array([ee,ff])
>>> b = a
>>> a[1] = gg
>>> ee[1] = 99911
>>> a
array([[  1,   2],
       [100, 200]])
>>> b
array([[  1,   2],
       [100, 200]])
>>> np.shares_memory(a,b)
True
```
#【B7】2次元,ndarray,スライス
```py
>>> ee = np.array([1,2])
>>> ff = np.array([3,4])
>>> gg = np.array([100,200])
>>>
>>> a = np.array([ee,ff])
>>> b = a[:]
>>> a[1] = gg
>>> ee[1] = 99911
>>> a
array([[  1,   2],
       [100, 200]])
>>> b
array([[  1,   2],
       [100, 200]])
>>> np.shares_memory(a,b)
True
```
#【B8】2次元,ndarray,numpyのcopy関数
```py
>>> ee = np.array([1,2])
>>> ff = np.array([3,4])
>>> gg = np.array([100,200])
>>>
>>> a = np.array([ee,ff])
>>> b = a.copy()
>>> a[1] = gg
>>> ee[1] = 99911
>>> a
array([[  1,   2],
       [100, 200]])
>>> b
array([[1, 2],
       [3, 4]])
>>> np.shares_memory(a,b)
False
```
#【B9】2次元,ndarray,copyモジュールのcopy関数
```py
>>> ee = np.array([1,2])
>>> ff = np.array([3,4])
>>> gg = np.array([100,200])
>>>
>>> a = np.array([ee,ff])
>>> b = copy.copy(a)
>>> a[1] = gg
>>> ee[1] = 99911
>>> a
array([[  1,   2],
       [100, 200]])
>>> b
array([[1, 2],
       [3, 4]])
>>> np.shares_memory(a,b)
False
```
#【B10】2次元,ndarray,copyモジュールのdeepcopy関数
```py
>>> ee = np.array([1,2])
>>> ff = np.array([3,4])
>>> gg = np.array([100,200])
>>>
>>> a = np.array([ee,ff])
>>> b = copy.deepcopy(a)
>>> a[1] = gg
>>> ee[1] = 99911
>>> a
array([[  1,   2],
       [100, 200]])
>>> b
array([[1, 2],
       [3, 4]])
>>> np.shares_memory(a,b)
False
```

補足

```
>>>
>>>
>>>
>>> #【A4_b】2次元,list,スライス
...
>>> a = [[1,2],[3,4]]
>>> b = a[:][:]
>>> a[0] = [900,9000]#変更
>>>        #（topレベルは、コピーされていることを示すため）
... a[1][1] = 99911
>>> a
[[900, 9000], [3, 99911]]
>>> b
[[1, 2], [3, 99911]]
>>>
```

#まとめ
コメントなどあれば、お願いします。

#関連（本人）
[pythonをストレスなく使う！（Python Pocket Reference (O'REILLY)が、分かり易いっ)](https://qiita.com/enoughspacefor/items/c2a09e8adef6c2cc61c2)