DEV Community

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

Posted on • Edited on

Shallow Copy & Deep Copy in Python (4)

Buy Me a Coffee

*Memos:

  • My post explains a set and copy.
  • My post explains the shallow and deep copy of a list.
  • 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 a dictionary.
  • My post explains the shallow and deep copy of an iterator.
  • My post explains variable assignment.

<A set with an iterator>

A set can have a tuple and iterator but cannot have a set, list and dictionary.

<Normal Copy>:

*Memos:

  • A and B refer to the same shallow set and deep iterator.
  • is keyword can check if v1 and v2 refer to the same set or iterator.
  # Shallow set #
#   ↓         ↓ 
A = {iter(['a'])}
   # ↑↑↑↑↑↑↑↑↑
 # Deep iterator #
B = A

print(A) # {<list_iterator object at 0x000001F95F9C6410>}
print(B) # {<list_iterator object at 0x000001F95F9C6410>}
print(A is B) # True

v = B.pop()

print(v) # <list_iterator object at 0x000001F95F9C6410>
print(A) # set()
print(B) # set()
Enter fullscreen mode Exit fullscreen mode

<Shallow Copy>:

copy() can do shallow copy as shown below:

*Memos:

  • A and B refer to different shallow sets.
  • A and B refer to the same deep iterator.
A = {iter(['a'])}

B = A.copy() # Here

print(A) # {<list_iterator object at 0x000001F9606954E0>}
print(B) # {<list_iterator object at 0x000001F9606954E0>}
print(A is B) # False

v1 = A.pop()
v2 = B.pop()

print(v1) # <list_iterator object at 0x000001F9606954E0>
print(v2) # <list_iterator object at 0x000001F9606954E0>
print(v1 is v2) # True

print(next(v1)) # a
print(next(v2)) # StopIteration:
Enter fullscreen mode Exit fullscreen mode

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

from copy import copy

A = {iter(['a'])}
B = copy(A) # Here

print(A) # {<list_iterator object at 0x000001F95F9CD510>}
print(B) # {<list_iterator object at 0x000001F95F9CD510>}

print(A is B) # False

v1 = A.pop()
v2 = B.pop()

print(v1) # <list_iterator object at 0x000001F95F9CD510>
print(v2) # <list_iterator object at 0x000001F95F9CD510>
print(v1 is v2) # True

print(next(v1)) # a
print(next(v2)) # StopIteration:
Enter fullscreen mode Exit fullscreen mode

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

A = {iter(['a'])}
B = set(A) # Here

print(A) # {<list_iterator object at 0x000001F9605E3730>}
print(B) # {<list_iterator object at 0x000001F9605E3730>}

print(A is B) # False

v1 = A.pop()
v2 = B.pop()

print(v1) # <list_iterator object at 0x000001F9605E3730>
print(v2) # <list_iterator object at 0x000001F9605E3730>
print(v1 is v2) # True

print(next(v1)) # a
print(next(v2)) # StopIteration:
Enter fullscreen mode Exit fullscreen mode

<Deep Copy>:

deepcopy() can do deep copy:

*Memos:

  • A and B refer to the different shallow sets and deep iterators.
  • deepcopy() should be used because it's safe, doing copy deeply.
from copy import deepcopy

A = {iter(['a'])}
B = deepcopy(A) # Here

print(A) # {<list_iterator object at 0x000001F96065DE40>}
print(B) # {<list_iterator object at 0x000001F960695CC0>}

print(A is B) # False

v1 = A.pop()
v2 = B.pop()

print(v1) # <list_iterator object at 0x000001F96065DE40>
print(v2) # <list_iterator object at 0x000001F960695CC0>
print(v1 is v2) # False

print(next(v1)) # a
print(next(v2)) # a
Enter fullscreen mode Exit fullscreen mode

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

from copy import copy

A = {iter(['a'])}
B = A.copy() # Here

print(A) # {<list_iterator object at 0x000001F9604F6410>}
print(B) # {<list_iterator object at 0x000001F9604F6410>}

print(A is B) # False

v1 = copy(A.pop()) # Here
v2 = copy(B.pop()) # Here

print(v1) # <list_iterator object at 0x000001F9604F7910>
print(v2) # <list_iterator object at 0x000001F9605E3190>
print(v1 is v2) # False

print(next(v1)) # a
print(next(v2)) # a
Enter fullscreen mode Exit fullscreen mode

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

from copy import copy

A = {iter(['a'])}
B = set(A) # Here

print(A) # {<list_iterator object at 0x000001F95F9BDF90>}
print(B) # {<list_iterator object at 0x000001F95F9BDF90>}

print(A is B) # False

v1 = copy(A.pop()) # Here
v2 = copy(B.pop()) # Here

print(v1) # <list_iterator object at 0x000001F96065DFF0>
print(v2) # <list_iterator object at 0x000001F96065D360>
print(v1 is v2) # False

print(next(v1)) # a
print(next(v2)) # a
Enter fullscreen mode Exit fullscreen mode

Additionally, the below is the 3D set with a 2D iterator:

from copy import deepcopy

A = {iter([iter(['a'])])}
B = deepcopy(A) # Here

print(A) # {<list_iterator object at 0x0000029DDF277B20>}
print(B) # {<list_iterator object at 0x0000029DE0049210>}

print(A is B) # False

v1 = A.pop()
v2 = B.pop()

print(v1) # <list_iterator object at 0x0000029DDF277B20>
print(v2) # <list_iterator object at 0x0000029DE0049210>
print(v1 is v2) # False

v3 = next(v1)
v4 = next(v2)

print(next(v3)) # a
print(next(v4)) # a
print(v3 is v4) # False
Enter fullscreen mode Exit fullscreen mode

Top comments (0)