Worked for 10 years next year, write blog for the first time, hope have write wrong place, colleague gives advice in time.
Let’s explore assignment, shallow copy, and deep copy in Python.
There is no copying of atomic type data in Python; references to the original memory address are used
There are three types of object copy used in Python: assignment, shallow copy, and deep copy.
I. [Assignment]
In python, assignments and operators perform simple object references. Those of you who have used C++ know the benefits of references:
Eg: >>> la = [1,2,3,4,5,’a’,[‘b_1′,’b_2’]]
lb = la la.append(6) la
[1, 2, 3, 4, 5, ‘a’, [‘a_1’, ‘a_2’], 6]
lb
[1, 2, 3, 4, 5, ‘a’, [‘a_1’, ‘a_2’], 6]
id(la)
44306560
id(lb)
44306560
la is lb
True
[id(x) for x in la, lb]
[44306560, 44306560]
In this case, lb and LA refer to the same memory address, which is 44306560. So when you modify LA, lb also changes because the same memory content changes. This is easy to understand.
Return true if they have the same address and the same content.
Assignment operations (including object assignment, parameter passing, return value passing, etc.) have no memory overhead other than that for lb variables.
Changing LA affects LB; In the same way, modifying lb affects LA.
【 Shallow copy 】
A shallow copy creates a new object whose contents are references to the original object.
Three means of implementation:
A), slice operation: lb=la[:] or LB = [I for I in La]
B) factory function :lb = list(la)
C), copy module copy function :lb = copy. Copy (la)
eg:
lbs=la[:] id(lbs)
44495376
id(la)
44306560
import copy lb = copy.copy(la) id(lb)
43251832
id(la)
44306560
[id(x) for x in la]
[5546784, 5546772, 5546760, 5546748, 5546736, 5755824, 44494440, 5546724]
[id(x) for x in lb]
[5546784, 5546772, 5546760, 5546748, 5546736, 5755824, 44494440, 5546724]
La.append (7)# Add atomic type element ——>lb not affected by la
[1, 2, 3, 4, 5, ‘a’, [‘a_1’, ‘a_2’], 6, 7]
lb
[1, 2, 3, 4, 5, ‘a’, [‘a_1’, ‘a_2’], 6]
La [5]=’a0’# Modify atomic type element ——>lb is not affected by La
[1, 2, 3, 4, 5, ‘a0’, [‘a_1’, ‘a_2’], 6, 7]
lb
[1, 2, 3, 4, 5, ‘a’, [‘a_1’, ‘a_2’], 6]
La [6].append(‘a_3’)# modify the atom type element inside the nested layer ——>lb affected la
[1, 2, 3, 4, 5, ‘a0’, [‘a_1’, ‘a_2’, ‘a_3’], 6, 7]
lb
[1, 2, 3, 4, 5, ‘a’, [‘a_1’, ‘a_2’, ‘a_3’], 6]
[id(x) for x in la]
[5546784, 5546772, 5546760, 5546748, 5546736, 44420728,44494440, 5546724, 5546712]
[id(x) for x in lb]
[5546784, 5546772, 5546760, 5546748, 5546736, 5755824,44494440, 5546724]
Pay attention to the above two red fonts ***
44420728 and 5755824 Since LA [5]=’ A0 ‘, what is actually done is: now apply for a block of memory, record ‘A0 ‘, and change the reference value of la[5] to the value number of this memory. Here, too, a reference is performed.
44494440: [‘a_1’, ‘a_2’, ‘a_3’] is nested with the same memory address
Shallow copy creates new lb, not LA, using IS to see that they are not the same object, using ID to see that they do not point to the same memory.
But when we use id(x) for x in la and id(x) for x in lb without changing the elements inside, we can see that they contain the same address.
In this case, LA and LB are different objects, but the internal elements do have the same memory address
Note, however, that a shallow copy is called a shallow copy because it only copies one layer, and there is a nested list in LA. If we modify it, the situation will be different.
La [5]. Append (” a_3 “). Look at the LB and you’ll see that the LB has changed as well. The reason: you have modified the nested list. If you modify an outer element, you modify its reference to point to another location, you modify an element in a nested list, the address of the list doesn’t change, it points to the same location.
【 deep copy 】
Deepcopy: the deepcopy function in the copy module. (Only one kind)
Deep copy: Copies all elements of an object, including multiple nested elements. So it’s a completely new piece of memory that has nothing to do with the data source. Expensive
Eg:
la
[1, 2, 3, 4, 5, ‘a0’, [‘a_1’, ‘a_2’, ‘a_3’, ‘a_4’], 6, 7]
lb = copy.deepcopy(la) [id(x) for x in (la,lb)]
[44306560, 44496776]#2 different memory addresses
[id(x) for x in la]
[5546784, 5546772, 5546760, 5546748, 5546736, 44420728,44494440, 5546724, 5546712] [5546784, 5546772, 5546760, 5546748, 5546736, 44420728,44494440, 5546724, 5546712
[id(x) for x in lb]
[5546784, 5546772, 5546760, 5546748, 5546736, 44420728,44493680, 5546724, 5546712] [5546784, 5546772, 5546760, 5546748, 5546736, 44420728,44493680, 5546724, 5546712
lb.append(8) lb
[1, 2, 3, 4, 5, ‘a0, [‘ a_1 and a_2,’ a_3 ‘, ‘a_4], 6, 7, 8] # of lb elements add la would not be affected
la
[1, 2, 3, 4, 5, ‘a0’, [‘a_1’, ‘a_2’, ‘a_3’, ‘a_4’], 6, 7]
[id(x) for x in lb]
[5546784, 5546772, 5546760, 5546748, 5546736, 44420728, 44493680, 5546724, 5546712, 5546700]
Lb [0]=9 # Changing LB does not affect LA LB either
[9, 2, 3, 4, 5, ‘a0’, [‘a_1’, ‘a_2’, ‘a_3’, ‘a_4’], 6, 7, 8]
la
[1, 2, 3, 4, 5, ‘a0’, [‘a_1’, ‘a_2’, ‘a_3’, ‘a_4’], 6, 7]
[id(x) for x in lb]
[5546688, 5546772, 5546760, 5546748, 5546736, 44420728, 44493680, 5546724, 5546712, 5546700]
[id(x) for x in la]
[5546784, 5546772, 5546760, 5546748, 5546736, 44420728, 44494440, 5546724, 5546712]
Even if the nested list has a deeper level, it doesn’t matter because the deep-copied object is completely new and no longer has anything to do with the original object.
Warning about copy operations
1. There is no copying of non-container types such as numbers, characters, and other “atomic” types. All that is produced is a reference to the original object.
2. If the tuple variable values contain objects of atomic type, even if a deep copy is used, only a shallow copy can be obtained. ———————————————— Copyright notice: This article is originally published BY CSDN blogger “Casual Wind”. It follows CC 4.0 BY-SA copyright agreement. Please attach the original source link and this statement. Original link: blog.csdn.net/Windgs_YF/a…