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

*Memo for shallow and deep copy:

*Memo for others:


Different lists are referred to, shallow-copied and deep-copied.


A 2D list is experimented, doing assignment and shallow and deep copy as shown below:

*Memo:

  • A 2D list can be shallow-copied and deep-copied.
  • There are an assignment and 2 kinds of copies, shallow copy and deep copy:
    • An assignment is to create the one or more references to the original top level object and (optional) original lower levels' objects, keeping the same values as before.
    • A shallow copy is to create the one or more references to the new top level object and (optional) original lower levels' objects, keeping the same values as before.
    • A deep copy is to create the two or more references to the new top level object and the new lower levels' objects which you desire but at least the new 2nd level objects, keeping the same values as before:
      • A deep copy is the multiple recursions of a shallow copy so a deep copy can be done with multiple shallow copies.
    • Basically, immutable(hashable) objects aren't copied to save memory like str, bytes, int, float, complex, bool and tuple.

<Assignment>:

*Memo:

  • v1 and v2 refer to the same outer and inner list.
  • is keyword can check if v1 and v2 refer to the same outer and/or inner list.

A 2D list is assigned to a variable without copied as shown below:

     ##### Outer list #####
#    ↓↓↓↓↓↓↓↓↓↓↓          ↓ 
v1 = ['a', 'b', ['c', 'd']]
v2 = v1       # ↑↑↑↑↑↑↑↑↑↑ Inner 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] = 'X'
v2[2][0] = 'Y'
          #       ↓↓↓   ↓↓↓
print(v1) # ['a', 'X', ['Y', 'd']]
print(v2) # ['a', 'X', ['Y', 'd']]
          #       ↑↑↑   ↑↑↑
Enter fullscreen mode Exit fullscreen mode

<Shallow copy>:

*Memo:

  • v1 and v2 refer to different outer lists and the same inner list.

list.copy() can shallow-copy the 2D list as shown below:

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

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] = 'X'
v2[2][0] = 'Y'
          #       ↓↓↓   ↓↓↓
print(v1) # ['a', 'b', ['Y', 'd']]
print(v2) # ['a', 'X', ['Y', 'd']]
          #       ↑↑↑   ↑↑↑
Enter fullscreen mode Exit fullscreen mode

copy.copy() can shallow-copy a 2D list as shown below:

import copy

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

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] = 'X'
v2[2][0] = 'Y'
          #       ↓↓↓   ↓↓↓
print(v1) # ['a', 'b', ['Y', 'd']]
print(v2) # ['a', 'X', ['Y', 'd']]
          #       ↑↑↑   ↑↑↑
Enter fullscreen mode Exit fullscreen mode

list() can shallow-copy a 2D list as shown below:

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

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] = 'X'
v2[2][0] = 'Y'
          #       ↓↓↓   ↓↓↓
print(v1) # ['a', 'b', ['Y', 'd']]
print(v2) # ['a', 'X', ['Y', 'd']]
          #       ↑↑↑   ↑↑↑
Enter fullscreen mode Exit fullscreen mode

Slicing can shallow-copy the 2D list as shown below:

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

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] = 'X'
v2[2][0] = 'Y'
          #       ↓↓↓   ↓↓↓
print(v1) # ['a', 'b', ['Y', 'd']]
print(v2) # ['a', 'X', ['Y', 'd']]
          #       ↑↑↑   ↑↑↑
Enter fullscreen mode Exit fullscreen mode

<Deep copy>:

*Memo:

  • v1 and v2 refer to different outer and inner lists.

copy.deepcopy() can deep-copy a 2D list as shown below:

*Memo:

  • copy.deepcopy() should be used because it's safe, deeply copying a 2D list while list.copy(), copy.copy(), list() and slicing aren't safe, shallowly copying a 2D list.
import copy 

v1 = ['a', 'b', ['c', 'd']]
v2 = copy.deepcopy(v1)

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] = 'X'
v2[2][0] = 'Y'
          #       ↓↓↓   ↓↓↓
print(v1) # ['a', 'b', ['c', 'd']]
print(v2) # ['a', 'X', ['Y', 'd']]
          #       ↑↑↑   ↑↑↑
Enter fullscreen mode Exit fullscreen mode

list.copy() can deep-copy the 2D list, shallow-copying the outer and inner list as shown below:

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

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] = 'X'
v2[2][0] = 'Y'
          #       ↓↓↓   ↓↓↓
print(v1) # ['a', 'b', ['c', 'd']]
print(v2) # ['a', 'X', ['Y', 'd']]
          #       ↑↑↑   ↑↑↑
Enter fullscreen mode Exit fullscreen mode

copy.copy() can deep-copy a 2D list, shallow-copying the outer and inner list as shown below:

import copy

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

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] = 'X'
v2[2][0] = 'Y'
          #       ↓↓↓   ↓↓↓
print(v1) # ['a', 'b', ['c', 'd']]
print(v2) # ['a', 'X', ['Y', 'd']]
          #       ↑↑↑   ↑↑↑
Enter fullscreen mode Exit fullscreen mode

list() can deep-copy a 2D list, shallow-copying the outer and inner list as shown below:

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

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] = 'X'
v2[2][0] = 'Y'
          #       ↓↓↓   ↓↓↓
print(v1) # ['a', 'b', ['c', 'd']]
print(v2) # ['a', 'X', ['Y', 'd']]
          #       ↑↑↑   ↑↑↑
Enter fullscreen mode Exit fullscreen mode

Slicing can deep-copy the 2D list, shallow-copying the outer and inner list as shown below:

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

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] = 'X'
v2[2][0] = 'Y'
          #       ↓↓↓   ↓↓↓
print(v1) # ['a', 'b', ['c', 'd']]
print(v2) # ['a', 'X', ['Y', 'd']]
          #       ↑↑↑   ↑↑↑
Enter fullscreen mode Exit fullscreen mode

Additionally, copy.deepcopy() can deep-copy a 3D list as shown below:

import copy 

v1 = ['a', 'b', ['c', ['d']]]
v2 = copy.deepcopy(v1)

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] = 'X'
v2[2][0] = 'Y'
v2[2][1][0] = 'Z'
          #       ↓↓↓   ↓↓↓   ↓↓↓
print(v1) # ['a', 'b', ['c', ['d']]]
print(v2) # ['a', 'X', ['Y', ['Z']]]
          #       ↑↑↑   ↑↑↑   ↑↑↑
Enter fullscreen mode Exit fullscreen mode

Top comments (0)