About the behavior of copy, deepcopy and numpy.copy

I'm addicted to it, so make a note.

No copy, shallow copy, deep copy

If you assign list to another variable in python, it will be "passed by reference".

x = [1, 2, 3]
y = x
y[0] = 999
x  #The change to y also affected x.

>>> [999, 2, 3]

To avoid this (= pass by value), use copy.

from copy import copy
x = [1, 2, 3]
y = copy(x)  # x[:]But good(Rather, this one is simpler)
y[0] = 999
x  #Change to y did not affect

>>> [1, 2, 3]

So was the copy done completely? It's not. For example, nested lists are passed by reference.

from copy import copy
x = [[1, 2, 3], 4, 5]
y = copy(x)
y[0][0] = 999
x  #Even though it's a copy!

>>> [[999, 2, 3], 4, 5]

Therefore, if you want to copy everything including nesting completely, use deepcopy.

from copy import deepcopy
x = [[1, 2, 3], 4, 5]
y = deepcopy(x)
y[0][0] = 999
x

>>> [[1, 2, 3], 4, 5]

What about NumPy?

When I tried it, it seems that it is automatically decided whether to execute a shallow copy or a deep copy. The following two differ in whether the second list in x contains 6 or not ** only **.

import numpy as np
x = [[1, 2, 3], [4, 5]]
y = np.copy(x)
y[0][0] = 999
x

>>> [[999, 2, 3], [4, 5, 6]]
import numpy as np
x = [[1, 2, 3], [4, 5, 6]]
y = np.copy(x)
y[0][0] = 999
x

>>> [[1, 2, 3], [4, 5, 6]]

Apparently, a deep copy is performed for something that can be converted into an n-dimensional array. I think it's just a straightforward idea as long as the matrix is represented by nesting lists. By the way, the same is true for 3D.

import numpy as np
x = [[[1, 0], [2, 0], [3]],
     [[4, 0], [5, 0], [6, 0]]]
y = np.copy(x)
y[0][0][0] = 999
x

>>> [[[999, 0], [2, 0], [3]], [[4, 0], [5, 0], [6, 0]]]
import numpy as np
x = [[[1, 0], [2, 0], [3, 0]],
     [[4, 0], [5, 0], [6, 0]]]
y = np.copy(x)
y[0][0][0] = 999
x

>>> [[[1, 0], [2, 0], [3, 0]], [[4, 0], [5, 0], [6, 0]]]

Impressions

** deepcopy strongest! !! !! !! !! ** **

(For the time being) Officially, there are two problems with deep copy operations.

However, it doesn't hurt to have a slightly redundant copy for personal handling. Recursive processing isn't needed so often, and deepcopying may be a good choice in situations where you're addicted to it.

Recommended Posts

About the behavior of copy, deepcopy and numpy.copy
About the behavior of yield_per of SqlAlchemy
About the behavior of enable_backprop of Chainer v2
About the behavior of Model.get_or_create () of peewee in Python
About the behavior of Queue during parallel processing
About the * (asterisk) argument of python (and itertools.starmap)
Think about the next generation of Rack and WSGI
Personal notes about the integration of vscode and anaconda
About the ease of Python
About the components of Luigi
About the features of Python
Python # About reference and copy
Tank game made with python About the behavior of tanks
A memo about the behavior of bowtie2 during multiple hits
About the return value of pthread_mutex_init ()
About the return value of the histogram.
About the basic type of Go
About the upper limit of threads-max
About the size of matplotlib points
About the basics list of Python basics
About Boxplot and Violinplot that visualize the variability of independent data
I investigated the behavior of the difference between hard links and symbolic links
This and that of the inclusion notation.
I wanted to be careful about the behavior of Python's default arguments
About the virtual environment of python version 3.7
About sensor_mode and angle of view of picamera
Review the concept and terminology of regression
About the arguments of the setup function of PyCaret
About the relationship between Git and GitHub
The story of trying deep3d and losing
About the Normal Equation of Linear Regression
About the main tasks of image processing (computer vision) and the architecture used
About _ and __
The behavior of @property is different between class definition and old and new styles
Talking about the features that pandas and I were in charge of in the project
About the X-axis notation of Matplotlib bar graphs
Summary of the differences between PHP and Python
Full understanding of the concepts of Bellman-Ford and Dijkstra
See the behavior of drunkenness with reinforcement learning
The answer of "1/2" is different between python2 and 3
About the processing speed of SVM (SVC) of scikit-learn
About Django's Model.save () behavior and MySQL deadlock error
The behavior of signal () depends on the compile options
Organize the meaning of methods, classes and objects
Specifying the range of ruby and python arrays
Make a copy of the list in Python
Change the color of Fabric errors and warnings
About the difference between "==" and "is" in python
A note about the python version of python virtualenv
Compare the speed of Python append and map
About the development contents of machine learning (Example)
[Note] About the role of underscore "_" in Python
General description of the CPUFreq core and CPUFreq notifiers
Visualize the behavior of the sorting algorithm with matplotlib
Organize the super-basic usage of Autotools and pkg-config
I read and implemented the Variants of UKR
About cumulative assignment of lists and numpy arrays
Behavior of numpy.dot when passing 1d array and 2d array
A discussion of the strengths and weaknesses of Python
About shallow and deep copies of Python / Ruby
The nice and regrettable parts of Cloud Datalab