I understand the differences between shallow copy and deep copy as I have learnt in class. However the following doesn't make sense
import copy
a = [1, 2, 3, 4, 5]
b = copy.deepcopy(a)
print(a is b)
print(a[0] is b[0])
----------------------------
~Output~
>False
>True
----------------------------
Shouldn't print(a[0] is b[0])
evaluate to False as the objects and their constituent elements are being recreated at a different memory location in a deep copy? I was just testing this out as we had discussed this in class yet it doesn't seem to work.
copy() create reference to original object. If you change copied object - you change the original object. . deepcopy() creates new object and does real copying of original object to new one. Changing new deepcopied object doesn't affect original object.
Making a copy of the list is a way to defend against mutation; a deep copy is needed here to make copies of both the outer list and the inner lists (i.e. the rows), which are also mutable. But objects such as integers and strings are immutable, so their state cannot be modified.
In Shallow copy, a copy of the original object is stored and only the reference address is finally copied. In Deep copy, the copy of the original object and the repetitive copies both are stored.
The copyOf method does not make a deep copy, according to the documentation it returns a non-mutable view, i.e. a read-only list. It does not make copies of the elements in the list.
It was suggested in another answer that this may be due to the fact Python has interned objects for small integers. While this statement is correct, it is not what causes that behaviour.
Let's have a look at what happens when we use bigger integers.
> from copy import deepcopy
> x = 1000
> x is deepcopy(x)
True
If we dig down in the copy
module we find out that calling deepcopy
with an atomic value defers the call to the function _deepcopy_atomic
.
def _deepcopy_atomic(x, memo):
return x
So what is actually happening is that deepcopy
will not copy an atomic value, but only return it.
By example this is the case for int
, float
, str
, function
and more.
The reason of this behavior is that Python optimize small integers so they are not actually in different memory location. Check out the id
of 1
, they are always the same:
>>> x = 1
>>> y = 1
>>> id(x)
1353557072
>>> id(y)
1353557072
>>> a = [1, 2, 3, 4, 5]
>>> id(a[0])
1353557072
>>> import copy
>>> b = copy.deepcopy(a)
>>> id(b[0])
1353557072
Reference from Integer Objects:
The current implementation keeps an array of integer objects for all integers between
-5
and256
, when you create an int in that range you actually just get back a reference to the existing object. So it should be possible to change the value of1
. I suspect the behaviour of Python in this case is undefined. :-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With