*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 a list and the list with indexing.
<Normal Copy>:
*Memos:
-
v1
andv2
refer to the same shallow and deep list. -
is
keyword can check ifv1
andv2
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']]
# ↑↑↑ ↑↑↑
<Shallow Copy>:
list.copy() does shallow copy as shown below:
*Memos:
-
v1
andv2
refer to different shallow lists. -
v1
andv2
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']]
# ↑↑↑ ↑↑↑
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']]
# ↑↑↑ ↑↑↑
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']]
# ↑↑↑ ↑↑↑
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']]
# ↑↑↑ ↑↑↑
<Deep Copy>:
copy.deepcopy() does deep copy as shown below:
*Memos:
-
v1
andv2
refer to the different shallow and deep lists. -
copy.deepcopy()
should be used because it's safe, doing copy deeply whilelist.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']]
# ↑↑↑ ↑↑↑
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']]
# ↑↑↑ ↑↑↑
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']]
# ↑↑↑ ↑↑↑
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']]
# ↑↑↑ ↑↑↑
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']]
# ↑↑↑ ↑↑↑
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']]]
# ↑↑↑ ↑↑↑ ↑↑↑