DEV Community

Super Kai (Kazuya Ito)
Super Kai (Kazuya Ito)

Posted on • Edited on

Shallow Copy & Deep Copy in Python (1)

Buy Me a Coffee

*Memos:

  • My post explains the shallow and deep copy of a tuple.
  • My post explains the shallow copy of the set with a tuple.
  • My post explains the shallow and deep copy of the set with an iterator.
  • My post explains the shallow and deep copy of a dictionary.
  • My post explains the shallow and deep copy of an iterator.
  • My post explains variable assignment.

Normal Copy:

*Memos:

  • v1 and v2 refer to the same shallow and deep list.
  • is keyword can check if v1 and v2 refer to the same list.
     #### Shallow list ####
#    ↓↓↓↓↓↓↓↓↓↓↓          ↓ 
v1 = ['a', 'b', ['c', 'd']]
v2 = v1       # ↑↑↑↑↑↑↑↑↑↑
              # Deep list

print(v1) # ['a', 'b', ['c', 'd']]
print(v2) # ['a', 'b', ['c', 'd']]
print(v1 is v2, v1[2] is v2[2]) # True True

v2[1] = 'B'
v2[2][0] = 'C'
          #       ↓↓↓   ↓↓↓
print(v1) # ['a', 'B', ['C', 'd']]
print(v2) # ['a', 'B', ['C', 'd']]
          #       ↑↑↑   ↑↑↑
Enter fullscreen mode Exit fullscreen mode

Shallow Copy:

copy() can do shallow copy as shown below:

*Memos:

  • v1 and v2 refer to different shallow lists.
  • v1 and v2 refer to the same deep list.
v1 = ['a', 'b', ['c', 'd']]
v2 = v1.copy() # Here

print(v1) # ['a', 'b', ['c', 'd']]
print(v2) # ['a', 'b', ['c', 'd']]
print(v1 is v2, v1[2] is v2[2]) # False True

v2[1] = 'B'
v2[2][0] = 'C'
          #       ↓↓↓   ↓↓↓
print(v1) # ['a', 'b', ['C', 'd']]
print(v2) # ['a', 'B', ['C', 'd']]
          #       ↑↑↑   ↑↑↑
Enter fullscreen mode Exit fullscreen mode

The below with copy() which can do shallow copy is equivalent to the above:

from copy import copy

v1 = ['a', 'b', ['c', 'd']]
v2 = copy(v1) # Here

print(v1) # ['a', 'b', ['c', 'd']]
print(v2) # ['a', 'b', ['c', 'd']]
print(v1 is v2, v1[2] is v2[2]) # False True

v2[1] = 'B'
v2[2][0] = 'C'
          #       ↓↓↓   ↓↓↓
print(v1) # ['a', 'b', ['C', 'd']]
print(v2) # ['a', 'B', ['C', 'd']]
          #       ↑↑↑   ↑↑↑
Enter fullscreen mode Exit fullscreen mode

The below with list() which can do shallow copy is equivalent to the above:

v1 = ['a', 'b', ['c', 'd']]
v2 = list(v1) # Here

print(v1) # ['a', 'b', ['c', 'd']]
print(v2) # ['a', 'b', ['c', 'd']]
print(v1 is v2, v1[2] is v2[2]) # False True

v2[1] = 'B'
v2[2][0] = 'C'
          #       ↓↓↓   ↓↓↓
print(v1) # ['a', 'b', ['C', 'd']]
print(v2) # ['a', 'B', ['C', 'd']]
          #       ↑↑↑   ↑↑↑
Enter fullscreen mode Exit fullscreen mode

The below with slice which can do shallow copy is equivalent to the above:

v1 = ['a', 'b', ['c', 'd']]
v2 = v1[:] # Here

print(v1) # ['a', 'b', ['c', 'd']]
print(v2) # ['a', 'b', ['c', 'd']]
print(v1 is v2, v1[2] is v2[2]) # False True

v2[1] = 'B'
v2[2][0] = 'C'
          #       ↓↓↓   ↓↓↓
print(v1) # ['a', 'b', ['C', 'd']]
print(v2) # ['a', 'B', ['C', 'd']]
          #       ↑↑↑   ↑↑↑
Enter fullscreen mode Exit fullscreen mode

Deep Copy:

deepcopy() can do deep copy as shown below:

*Memos:

  • v1 and v2 refer to the different shallow and deep lists.
  • deepcopy() should be used because it's safe, doing copy deeply.
from copy import deepcopy

v1 = ['a', 'b', ['c', 'd']]
v2 = deepcopy(v1) # Here

print(v1) # ['a', 'b', ['c', 'd']]
print(v2) # ['a', 'b', ['c', 'd']]
print(v1 is v2, v1[2] is v2[2]) # False False

v2[1] = 'B'
v2[2][0] = 'C'
          #       ↓↓↓   ↓↓↓
print(v1) # ['a', 'b', ['c', 'd']]
print(v2) # ['a', 'B', ['C', 'd']]
          #       ↑↑↑   ↑↑↑
Enter fullscreen mode Exit fullscreen mode

The below with copy() which can do shallow copy is equivalent to the above:

v1 = ['a', 'b', ['c', 'd']]
v2 = v1.copy() # Here
v2[2] = v1[2].copy() # Here

print(v1) # ['a', 'b', ['c', 'd']]
print(v2) # ['a', 'b', ['c', 'd']]
print(v1 is v2, v1[2] is v2[2]) # False False

v2[1] = 'B'
v2[2][0] = 'C'
          #       ↓↓↓   ↓↓↓
print(v1) # ['a', 'b', ['c', 'd']]
print(v2) # ['a', 'B', ['C', 'd']]
          #       ↑↑↑   ↑↑↑
Enter fullscreen mode Exit fullscreen mode

The below with copy() which can do shallow copy is equivalent to the above:

from copy import copy

v1 = ['a', 'b', ['c', 'd']]
v2 = copy(v1) # Here
v2[2] = copy(v1[2]) # Here

print(v1) # ['a', 'b', ['c', 'd']]
print(v2) # ['a', 'b', ['c', 'd']]
print(v1 is v2, v1[2] is v2[2]) # False False

v2[1] = 'B'
v2[2][0] = 'C'
          #       ↓↓↓   ↓↓↓
print(v1) # ['a', 'b', ['c', 'd']]
print(v2) # ['a', 'B', ['C', 'd']]
          #       ↑↑↑   ↑↑↑
Enter fullscreen mode Exit fullscreen mode

The below with list() which can do shallow copy is equivalent to the above:

v1 = ['a', 'b', ['c', 'd']]
v2 = list(v1) # Here
v2[2] = list(v1[2]) # Here

print(v1) # ['a', 'b', ['c', 'd']]
print(v2) # ['a', 'b', ['c', 'd']]
print(v1 is v2, v1[2] is v2[2]) # False False

v2[1] = 'B'
v2[2][0] = 'C'
          #       ↓↓↓   ↓↓↓
print(v1) # ['a', 'b', ['c', 'd']]
print(v2) # ['a', 'B', ['C', 'd']]
          #       ↑↑↑   ↑↑↑
Enter fullscreen mode Exit fullscreen mode

The below with slice which can do shallow copy is equivalent to the above:

v1 = ['a', 'b', ['c', 'd']]
v2 = v1[:] # Here
v2[2] = v1[2][:] # Here

print(v1) # ['a', 'b', ['c', 'd']]
print(v2) # ['a', 'b', ['c', 'd']]
print(v1 is v2, v1[2] is v2[2]) # False False

v2[1] = 'B'
v2[2][0] = 'C'
          #       ↓↓↓   ↓↓↓
print(v1) # ['a', 'b', ['C', 'd']]
print(v2) # ['a', 'B', ['C', 'd']]
          #       ↑↑↑   ↑↑↑
Enter fullscreen mode Exit fullscreen mode

Additionally, the below is a 3D list:

from copy import deepcopy

v1 = ['a', 'b', ['c', ['d']]]
v2 = deepcopy(v1) # Here

print(v1) # ['a', 'b', ['c', ['d']]]
print(v2) # ['a', 'b', ['c', ['d']]]
print(v1 is v2, v1[2] is v2[2], v1[2][1] is v2[2][1]) # False False False

v2[1] = 'B'
v2[2][0] = 'C'
v2[2][1][0] = 'D'
          #       ↓↓↓   ↓↓↓   ↓↓↓
print(v1) # ['a', 'b', ['c', ['d']]]
print(v2) # ['a', 'B', ['C', ['D']]]
          #       ↑↑↑   ↑↑↑   ↑↑↑
Enter fullscreen mode Exit fullscreen mode

Top comments (0)