jay
jay

Reputation: 61

np.copy(obj) vs obj.copy() vs copy.copy(obj) vs copy.deepcopy(obj)

np.copy(obj) vs obj.copy() vs copy.copy(obj) vs copy.deepcopy(obj)

I see that there are basically four methods we can use for copying object in Python.
I am not crystal clear about the differences between the four.

Someone please explain the differences from the ground.

Thanks.

Upvotes: 1

Views: 79

Answers (1)

jupiterbjy
jupiterbjy

Reputation: 3503

TL;DR they differ in copy method:

  • Shallow copy:
    • numpy.copy()
    • (dict | list | ...).copy()
    • copy.copy()
  • Deep copy:
    • copy.deepcopy()

Also by the purpose:

  • Copy data structure:
    • numpy.copy()
    • (dict | list | ...).copy()
  • Copy object (data structure ⊂ object):
    • copy.copy()
    • copy.deepcopy()

Plus, copy.copy() or copy.deepcopy() will internally call obj.__copy__() and obj.__deepcopy__() methods respectively, if exists - Which means user classes can control the copying behavior.


Explanation about Shallow copy & Deep copy

There's 2 kind of copy in python: Shallow copy and Deep copy.

From Python documents:

The difference between shallow and deep copying is only relevant for compound objects (objects that contain other objects, like lists or class instances):

  • A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.

  • A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.

Such difference is best shown when we copy class instance.

>>> class SomeClass:
...     pass

>>> a = [SomeClass()]
>>> b = a.copy()

>>> a[0] == b[0]
True

>>> id(a[0])
2778700770576
>>> id(b[0])
2778700770576

# Not actually copied, referencing to same instance.
>>> import copy
>>> a = [SomeClass()]
>>> b = copy.deepcopy(a)

>>> a[0] == b[0]
False

>>> id(a[0])
2778695702544
>>> id(b[0])
2778717746032

# Actually copied into different instance

For shallow copy, if your data contain compound object - most commonly list, dict, user classes, etc - and you have to work on it, make sure to use Deep copy to avoid things like below:

>>> a = [[0], [0]]
>>> b = a.copy()

>>> b[0].append(10)

>>> a
[[0, 10], [0]]
>>> b
[[0, 10], [0]]

# ---

>>> a = [[0], [0]]
>>> b = copy.deepcopy(a)

>>> b[0].append(10)

>>> a
[[0], [0]]
>>> b
[[0, 10], [0]]

Upvotes: 1

Related Questions