MaverickD
MaverickD

Reputation: 1657

visualizing difference between deep and shallow copy

I understand what is the difference between deep and shallow copy.

A deep copy copies an object into another. This means that if you make a change to a copy of an object, it won’t affect the original object. In Python, we use the function deepcopy() for this, and we import the module copy. We use it like:

In order to visualize it i used python tutor and got this,

import copy
a = [1, 2, 3]

b = copy.deepcopy(a)

enter image description here

Which makes sense, since it created a new object when I used deepcopy() function.

On the other hand shallow copy is,

A shallow copy, however, copies one object’s reference to another. So, if we make a change in the copy, it will affect the original object. For this, we have the function copy().

But when I used shallow copy, why do I get the same result?

import copy
a = [1, 2, 3]

b = copy.deepcopy(a)
c = copy.copy(a)

enter image description here

From my understanding, Shallow copy should reference the same object (i.e. a instead of creating a new object as follows,

c = a

enter image description here

Can someone please tell me why both deepcopy() and shallow copy creating a new object?

Upvotes: 2

Views: 811

Answers (1)

e.s.
e.s.

Reputation: 1371

copy makes a copy of the parent object only. It makes a new object that points to all the same attributes as the original object. deepcopy - 1) copies the original object, 2) then runs copy on each attribute pointed to, then makes copies of any attributes that those other copies point to etc....

In your case, since the attributes of your list are immutable, copy and deepcopy are interchangeable. if you have a list of lists, or list of lists of lists or ... then you use deepcopy.

Here is a quick example of the difference:

>>> example = [[1, 2, 3], [4, 5, 6]]
>>> same_obj = example
>>> shallow_copy = copy(example)
>>> deep_copy = deepcopy(example)
>>> example.append([7, 8, 9])
>>> print(example)
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> print(same_obj)
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> print(shallow_copy)
[[1, 2, 3], [4, 5, 6]]
>>> example[0].sort(reverse=True)
>>> print(example)
[[3, 2, 1], [4, 5, 6], [7, 8, 9]]
>>> print(shallow_copy)
[[3, 2, 1], [4, 5, 6]]
>>> print(deep_copy)
[[1, 2, 3], [4, 5, 6]]

shallow_copy and example are two different objects. They have indexes which point to other objects (in this case, lists). These indexes are all pointing to the same objects, so if you mutate the object that either list points to, the mutation shows up in both lists. deepcopy, not only copied the parent list, but also copied each list that the parent list pointed to. so any changes to a sub-list did not affect deep_copy in any way.

Upvotes: 2

Related Questions