Shallow Copy & Deep Copy in Python (4)
Super Kai (Kazuya Ito)

Super Kai (Kazuya Ito) @hyperkai

About: I'm a web developer. Buy Me a Coffee: ko-fi.com/superkai SO: stackoverflow.com/users/3247006/super-kai-kazuya-ito X(Twitter): twitter.com/superkai_kazuya FB: facebook.com/superkai.kazuya

Joined:
Oct 21, 2021

Shallow Copy & Deep Copy in Python (4)

Publish Date: Jun 15
0 0

Buy Me a Coffee

*Memos:

  • 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 a set and copy.

<A set with an iterator>

A set can have the hashable types of elements like frozenset, tuple, iterator, etc but cannot have the unhashable types of elements like set, list, dict, etc:

<Normal Copy>:

*Memo:

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

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

*Memo:

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

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

import copy

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

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

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

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

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

*Memo:

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

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

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

import copy

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

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

print(A is B)
# False

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

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

import copy

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

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

print(A is B)
# False

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

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:

import copy

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

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

Comments 0 total

    Add comment