darxtrix
darxtrix

Reputation: 2040

Why there is no difference between shallow copy and deep copy for a list of immutables

Suppose i have a python list l consisting of immutables.When i am doing a shallow copy and a deep copy, the result is same:

>>> a = (1,2) # immutable types
>>> b = (3,4)
>>> l = [a,b] # a list containing immutable types

>>> import copy
>>> y = copy.copy(l) # shallow copy
>>> z = copy.deepcopy(l) # deep copy

>>> id(l[0])
139857440375584
>>> id(y[0])
139857440375584
>>> id(z[0])
139857440375584 # all have the same id's , so all refer to the same object

Does it means that shallow copy and deep copy has a meaning only for collections of mutable types because immutable types never changes. But if we want to achieve a deep copy like behavior for the these type of collections how can we do that?

Regards.

Upvotes: 2

Views: 936

Answers (3)

pepr
pepr

Reputation: 20770

For this specific case, creating the small-integer objects is optimized. Even when doing a simple assignment, you can observe the same identification of the object even though they should not know each other:

>>> a = 1
>>> b = 5
>>> c = 1
>>> d = 5
>>> id(a)
1815461288
>>> id(c)
1815461288
>>> id(b)
1815461352
>>> id(d)
1815461352

Upvotes: 0

that other guy
that other guy

Reputation: 123490

thefourtheye explains why there's no difference. If you want to do it anyways, you can kludge it by pickling:

import pickle

a = (1,2)
b = (3,4)
l = [a,b]

z = pickle.loads(pickle.dumps(l))

print id(l[0])
print id(z[0])

Obviously, this should never be necessary.

Upvotes: 2

thefourtheye
thefourtheye

Reputation: 239483

Since you cannot change the immutable objects, there is no point in creating copies of the same while copying.

Shallow Copy

As per copy's source code, shallow copy of immutable types is done like this

def _copy_immutable(x):
    return x

for t in (type(None), int, long, float, bool, str, tuple,
          frozenset, type, xrange, types.ClassType,
          types.BuiltinFunctionType, type(Ellipsis),
          types.FunctionType, weakref.ref):
    d[t] = _copy_immutable

For all the immutable types, the _copy_immutable function returns the object as it is, during shallow copy.

Deep Copy

The same way, during the deepcopy of tuples, the object is returned as is, as per the _deepcopy_tuple function,

d = id(x)
try:
    return memo[d]

Upvotes: 3

Related Questions