*Memo for shallow and deep copy:
- My post explains a list.
- My post explains a tuple.
- My post explains the set with a frozenset.
- My post explains the set with a tuple.
- My post explains a frozenset.
- My post explains a dictionary.
- My post explains an iterator.
- My post explains a string.
- My post explains a bytes.
- My post explains a bytearray.
- My post explains a range.
*Memo for shallow and deep copy:
- My post explains a set (1).
Different sets are referred to, shallow-copied and deep-copied.
The 2D set with a 1D iterator is experimented, doing assignment and shallow and deep copy as shown below:
*Memo:
- The 2D set with a 1D iterator can be shallow-copied and deep-copied.
- A set can have the hashable types of elements like
frozenset
,tuple
,iterator
, etc but cannot have the unhashable types of elements likeset
,list
,dict
, etc. - Different iterators are referred to if copied according to the experiments.
- 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
andtuple
.
<Assignment>:
*Memo:
-
A
andB
refer to the same outer set and inner iterator. -
is
keyword can check ifA
andB
refer to the same outer set and/or inner iterator.
The 2D set with a 1D iterator is assigned to a variable without copied as shown below:
### Outer set ###
# ↓ ↓
A = {iter([0, 1, 2])}
# ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ Inner iterator
B = A
print(A) # {<list_iterator object at 0x000001F95F9C6410>}
print(B) # {<list_iterator object at 0x000001F95F9C6410>}
print(A is B)
# True
print(B.pop()) # <list_iterator object at 0x000001F95F9C6410>
print(A) # set()
print(B) # set()
<Shallow copy>:
*Memo:
-
A
andB
refer to different outer sets and the same inner iterator.
set.copy() can shallow-copy the 2D set with a 1D iterator as shown below:
A = {iter([0, 1, 2])}
B = A.copy()
print(A) # {<list_iterator object at 0x000001F9606954E0>}
print(B) # {<list_iterator object at 0x000001F9606954E0>}
print(A is B)
# False
A = A.pop()
B = B.pop()
print(A) # <list_iterator object at 0x000001F9606954E0>
print(B) # <list_iterator object at 0x000001F9606954E0>
print(A is B)
# True
print(next(A)) # 0
print(next(B)) # 1
print(next(A)) # 2
print(next(B)) # StopIteration:
copy.copy() can shallow-copy the 2D set with a 1D iterator as shown below:
import copy
A = {iter([0, 1, 2])}
B = copy.copy(A)
print(A) # {<list_iterator object at 0x000001F95F9CD510>}
print(B) # {<list_iterator object at 0x000001F95F9CD510>}
print(A is B)
# False
A = A.pop()
B = B.pop()
print(A) # <list_iterator object at 0x000001F95F9CD510>
print(B) # <list_iterator object at 0x000001F95F9CD510>
print(A is B)
# True
print(next(A)) # 0
print(next(B)) # 1
print(next(A)) # 2
print(next(B)) # StopIteration:
set() can shallow-copy the 2D set with a 1D iterator as shown below:
A = {iter([0, 1, 2])}
B = set(A)
print(A) # {<list_iterator object at 0x000001F9605E3730>}
print(B) # {<list_iterator object at 0x000001F9605E3730>}
print(A is B)
# False
A = A.pop()
B = B.pop()
print(A) # <list_iterator object at 0x000001F9605E3730>
print(B) # <list_iterator object at 0x000001F9605E3730>
print(A is B)
# True
print(next(A)) # 0
print(next(B)) # 1
print(next(A)) # 2
print(next(B)) # StopIteration:
<Deep copy>:
*Memo:
-
A
andB
refer to different outer sets and inner iterators.
copy.deepcopy() can deep-copy the 2D set with a 1D iterator as shown below:
*Memo:
-
copy.deepcopy()
should be used because it's safe, deeply copying the 2D set with a 1D iterator whileset.copy()
,copy.copy()
andset()
aren't safe, shallowly copying the 2D set with a 1D iterator.
from copy import deepcopy
A = {iter([0, 1, 2])}
B = deepcopy(A)
print(A) # {<list_iterator object at 0x000001F96065DE40>}
print(B) # {<list_iterator object at 0x000001F960695CC0>}
print(A is B)
# False
A = A.pop()
B = B.pop()
print(A) # <list_iterator object at 0x000001F96065DE40>
print(B) # <list_iterator object at 0x000001F960695CC0>
print(A is B)
# False
print(next(A)) # 0
print(next(B)) # 0
print(next(A)) # 1
print(next(B)) # 1
print(next(A)) # 2
print(next(B)) # 2
print(next(A))
print(next(B))
# StopIteration:
set.copy() and copy() can deep-copy the 2D set with a 1D iterator, shallow-copying the outer set and inner iterator as shown below:
import copy
A = {iter([0, 1, 2])}
B = A.copy()
print(A) # {<list_iterator object at 0x000001F9604F6410>}
print(B) # {<list_iterator object at 0x000001F9604F6410>}
print(A is B)
# False
A = copy.copy(A.pop())
B = copy.copy(B.pop())
print(A) # <list_iterator object at 0x000001F9604F7910>
print(B) # <list_iterator object at 0x000001F9605E3190>
print(A is B)
# False
print(next(A)) # 0
print(next(B)) # 0
print(next(A)) # 1
print(next(B)) # 1
print(next(A)) # 2
print(next(B)) # 2
print(next(A))
print(next(B))
# StopIteration:
set() and copy.copy() can deep-copy the 2D set with a 1D iterator, shallow-copying the outer set and inner iterator as shown below:
import copy
A = {iter([0, 1, 2])}
B = set(A)
print(A) # {<list_iterator object at 0x000001F95F9BDF90>}
print(B) # {<list_iterator object at 0x000001F95F9BDF90>}
print(A is B)
# False
A = copy.copy(A.pop())
B = copy.copy(B.pop())
print(A) # <list_iterator object at 0x000001F96065DFF0>
print(B) # <list_iterator object at 0x000001F96065D360>
print(A is B)
# False
print(next(A)) # 0
print(next(B)) # 0
print(next(A)) # 1
print(next(B)) # 1
print(next(A)) # 2
print(next(B)) # 2
print(next(A))
print(next(B))
# StopIteration:
Additionally, copy.deepcopy() can deep-copy the 3D set with a 2D iterator as shown below:
import copy
A = {iter([iter([0, 1, 2])])}
B = copy.deepcopy(A)
print(A) # {<list_iterator object at 0x0000029DDF277B20>}
print(B) # {<list_iterator object at 0x0000029DE0049210>}
print(A is B)
# False
A = A.pop()
B = B.pop()
print(A) # <list_iterator object at 0x0000029DDF277B20>
print(B) # <list_iterator object at 0x0000029DE0049210>
print(A is B)
# False
A = next(A)
B = next(B)
print(A) # <list_iterator object at 0x000002451219DC60>
print(B) # <list_iterator object at 0x000002451219E140>
print(A is B)
# False
print(next(A)) # 0
print(next(B)) # 0
print(next(A)) # 1
print(next(B)) # 1
print(next(A)) # 2
print(next(B)) # 2
print(next(A))
print(next(B))
# StopIteration:
Top comments (0)