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:

  • 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 a list and the list with indexing.

<Normal Copy>:

*Memo:

  • 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>:

list.copy() does shallow copy as shown below:

*Memo:

  • 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() 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.copy() which does shallow copy is equivalent to the above:

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] = '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 does shallow copy is equivalent to the above:

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] = '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 slicing which does shallow copy is equivalent to the above:

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] = '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>:

copy.deepcopy() does deep copy as shown below:

*Memo:

  • v1 and v2 refer to the different shallow and deep lists.
  • copy.deepcopy() should be used because it's safe, doing copy deeply while list.copy(), copy.copy(), list() and slicing aren't safe, doing copy shallowly.
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] = '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.copy() which does shallow copy is equivalent to the above:

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] = '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.copy() which does shallow copy is equivalent to the above:

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] = '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 does shallow copy is equivalent to the above:

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] = '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 slicing which does shallow copy is equivalent to the above:

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] = '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:

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] = '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)