Examples of variable and immutable data types in deep and shallow copies of Python
I hope it will be helpful for you who are learning Python. If there are any mistakes, please point them out. Thank you.
Experiment in python interaction mode
1. Data assignment
In[18]: list1 = [1,2,3,4,5,6] In[19]: list2 = list1 In[20]: id(list1) Out[20]: 139639962104008 In[21]: id(list2) Out[21]: 139639962104008 In[22]: list1.append("BMW") # Add an element to the list In[23]: print(list1) [1, 2, 3, 4, 5, 6, 'BMW'] In[24]: print(list2) [1, 2, 3, 4, 5, 6, 'BMW'] # The original data modification assignment changes as well. In[25]: id(list1) Out[25]: 139639962104008 In[26]: id(list2) Out[26]: 139639962104008 # Modify the original data memory address unchanged //Assignment refers to the same memory address of the list, adds new values to the list, stores the address of a new element in the list, and the address of the list itself does not change, so the IDs of list1 and list2 have not changed and new elements have been added. //Assignment is equivalent to full sharing of resources, and using reference counting in python saves memory usage space
2. Slice assignment of lists and modification of lists
In[2]: list = [1,2,3,4,5,6] In[3]: id(list) Out[3]: 140213469483848 In[4]: list2 = list[:] # Slice assignment In[5]: list2 Out[5]: [1, 2, 3, 4, 5, 6] In[6]: id(list2) Out[6]: 140213469654536 # After slicing, assignment produces a new memory address In[7]: list3 = list In[8]: list3 Out[8]: [1, 2, 3, 4, 5, 6] In[9]: id(list3) Out[9]: 140213469483848 # Direct assignment is to share the same address In[10]: id(list2) Out[10]: 140213469654536 In[11]: id(list) Out[11]: 140213469483848 In[12]: list.append(1) In[13]: list Out[13]: [1, 2, 3, 4, 5, 6, 1] In[14]: list2 Out[14]: [1, 2, 3, 4, 5, 6] # The slice assignment data did not change In[15]: list3 Out[15]: [1, 2, 3, 4, 5, 6, 1]
There are two ways to copy in python: deep copy and shallow copy.
Function: Shallow copy can save memory space, most of pytho is shallow copy. Shallow or deep copies can be made as required. For example, backing up important data and using deep copy if you don't want to be modified.
1. Shallow copy
# Import copy module import copy list = [1, 2, [1, 2]] list1 = copy.copy(list) # shallow copy print(list) print(list1) print(id(list)) print(id(list1)) list[-1][0] = "a" # Modify nested inner list list[0] = "b" # Modify the Outer List print(list) print(list1) print(id(list)) print(id(list1)) print("-------Here is the slice assignment modification data------------") list2 = [1, 2, [1, 2]] list3 = list2[:] # Slice assignment print(list2) print(list3) print(id(list2)) print(id(list3)) list2[-1][0] = "a" # Modify the list of layers list2[0] = "b" # Modify the Outer List print(list2) print(list3) print(id(list2)) print(id(list3)) //Operation results: [1, 2, [1, 2]] [1, 2, [1, 2]] 139845534794760 139845558797384 ['b', 2, ['a', 2]] # Original data list modification [1, 2, ['a', 2]] # After shallow copy, the outer layer of list1 does not change memory. 139845534794760 # Memory address or pre-modified address 139845558797384 -------Here is the slice assignment modification data------------ [1, 2, [1, 2]] [1, 2, [1, 2]] 140634594190344 140634594190856 ['b', 2, ['a', 2]] [1, 2, ['a', 2]] 140634594190344 140634594190856 //Modify the list of the outer layer, the outer layer does not change, when modifying the sublist of the inner layer, it does change.
2. Deep copy
import copy list = ['a', 2, ['b', 2]] list1 = copy.deepcopy(list) # deep copy print(list) print(list1) print(id(list)) print(id(list1)) list[0] = 'y' # Modify the outer list of lists list[-1][0] = 'z' # Modify the inner list of lists print(list) print(list1) print(id(list)) print(id(list1)) //Operation results: ['a', 2, ['b', 2]] ['a', 2, ['b', 2]] 140159390786568 140159390787080 ['y', 2, ['z', 2]] # The original data has been modified ['a', 2, ['b', 2]] # Deep copies will not be modified 140159390786568 140159390787080 //The inner and outer sides of list 1 do not change after deep copy list inner and outer layer modification. //Conclusion: //Shallow copy: Copying only the outer layer does not copy the sub-objects in the data, which can be understood as a shortcut in windows. //Deep copy: full copy, full copy
3. Deep and shallow copies of immutable types
import copy # Meta-ancestor of immutable type a = (1, 2, 3) b = copy.copy(a) # shallow copy c = copy.deepcopy(a) # deep copy print(a) print(b) print(c) print(id(a)) print(id(b)) print(id(c)) # Adding data to meta-ancestors a = a[:2] + ("a",) + a[2:] # It's actually reassignment. # A [0]= "w" meta-ancestor is an immutable type that cannot be modified print(a) print(b) print(c) print(id(a)) print(id(b)) print(id(c)) //Operation results: (1, 2, 3) (1, 2, 3) (1, 2, 3) 140484977573464 140484977573464 140484977573464 (1, 2, 'a', 3) # New memory addresses are generated because they are actually reassigned (1, 2, 3) # Shallow copy results (1, 2, 3) # Deep copy results 140484977319272 # New memory addresses are generated because they are actually reassigned 140484977573464 140484977573464 //In immutable types, both deep and shallow copies refer to the same memory address
4. Invariant Type Nested Variable Type Depth and Shallow Copies
import copy a = (1, 2, ["a", "b"]) b = copy.copy(a) # shallow copy c = copy.deepcopy(a) # deep copy print(a) print(b) print(c) print(id(a)) print(id(b)) print(id(c)) a[-1][0] = 3 # Modify the data in the variable type nested list # A [0]= "w" where the inner layer is immutable and cannot be modified print(a) print(b) print(c) print(id(a)) print(id(b)) print(id(c)) //Operation results: (1, 2, ['a', 'b']) (1, 2, ['a', 'b']) (1, 2, ['a', 'b']) 140092667158104 140092667158104 140092666850616 # Deep copy memory address changed (1, 2, [3, 'b']) # Change of original data (1, 2, [3, 'b']) # The inner variable type data memory address in shallow copy has changed (1, 2, ['a', 'b']) # Deep copy is the new memory address so it remains unchanged 140092667158104 140092667158104 # Modify inner variable type data, shallow copy outer memory address unchanged 140092666850616 //When encountering immutable types, attention should be paid to nested data types.