I have experienced peculiar bugs from this [:]
copy.
The docs say [:]
makes only a shallow copy but seems:
a = [1,2,3]
id(a)
3071203276L
b=a[:]
id(b)
3071234156L
id(a)
is not equal to id(b)
; how is that only a shallow copy?
Peculiar case:
import numpy as np
import random
a = np.array([1,2,3])
b=a[:]
random.shuffle(a)
b
changes correspondingly.
Probably the only thing that makes a deep copy is
deepcopy
.Because deep copies are expensive, as you need to track every object you copied.
Consider evil structures like this:
You certainly won't want to make a naive deep copy of this.
So yes, it is a shallow copy. But in your example, it is storing primitives, which will be copied as value, not as reference. So modifying one list won't modify the other.
id()
cannot be used to distinguish shallow and deep copiesIt distinguishes copies from non-copies (which have the same id).
Numpy arrays are different
Here, you only "shallow copy" the index, not the data which is in a backing storage. Use
.copy()
if you want to make sure you have a copy.Numpy defines what what a slice returns differently to the standard python library. This is because numpy is made to work with huge amounts of data. Copying these huge arrays is not always wanted, especially if the user only wanted a temporary view of the array. For instance,
arr[:100].sum()
sums the first 100 elements, without having to create a temporary shallow copy of the first 100 elements. Note that temporary views are only created for a basic slice.See the documentation for more details.
Numpy answer:
Arrays in numpy are views/indexes on a backing storage.
You can copy the view, without copying the backing storage...
See how changing b affected a? Yet they still have a different shape. Consider them to be views of the data; and the
b=a[:]
line copied just this view. I could even modify the shape ofb
. Because it is just an index to the data, that says where columns and rows are located in memory.If you want a copy of the backing storage in numpy, use
a.copy()
.It is a shallow copy, but changing
b
does not affecta
in this case because the elements are just numbers. If they were references thena
would be updated:vs
The difference is that the elements of list a and list b are the same. Changing mutable objects in either list also effects the elements in the other list.
In contrast there is deepcopy which tries to create a completely different set of objects.