This week encountered some problems, and then realized that the basic knowledge for a period of time did not consolidate, or have forgotten part, or need to review, here to make a note, record
Ex-Continued
A simple description of the problem encountered, the requirement is to write 2 print results
As you can see, a points to a list object, in Python, such an assignment statement, in fact, refers to a point where a points to the memory address of the list, which can be viewed as a pointer-like concept.
and B, notice that he's wrapping a object into a list and multiplying it by 5, so B should look like a big list with all the elements a
And when a object is append, the implication is that the list in memory is modified, and all objects that refer to this object will change
I printed the ID of a and, at the same time, printed the ID of the element a contained in the object B, so as to see that the ID of each element in the B list is the same as a
We can see that the ID of object A (memory address) is 10892296, although B wraps a into the new list, but this element refers to the same address object, you can use the following figure to explain
After that, we did a append operation on a, because the list was a mutable object, so his memory address did not change, but all objects referenced in memory for this address were changed together to see from the lower part of the line above the test graph.
This leads to the review of Python citation mechanism and shallow copy and deep copy.
Python's referral mechanism
Referral Mechanism Case 1
From the example above, we can see that Python's reference is passed, and the end result is that 2 objects refer to the same area in memory
So let's take a look at the following example
b through a, the same reference to the content of the address ID 17446024, 2 of the ID (memory address) is the same hair
So, through the operation of a a[0]=3 or a[3].append (6), the contents of this piece of memory will be modified (because the list is a mutable object, so the memory address does not change, which is later)
This is the most basic case of reference (in other words, because A and b all point to the same memory address, so the contents of B modified, can also reflect to a above)
Referral Mechanism Case 2
Let's look at one more case.
Looking at the subject seems to replace the element 2 with its own list, and perhaps the result should be a=[1,[1,2,3],3]
But not really!! You can see that there are infinitely many nesting in the middle of the red box
Why is that?
In fact, because a is pointing to the [1,2,3] list, in this case, it just takes the 2nd element of a to point to the object a itself, so it's just a structure that has changed! But, a still points to that object.
We can see by printing the ID of a, his point is not changed!!
Look, the point of a does not change.
What if we want to achieve the final output effect [1,[1,2,3],3], and how should we operate it?
Here, we need to use a shallow copy, the use can be as follows
Shallow copy and deep copy
Shallow copy
Now, to say shallow copy and deep copy, the above method is actually just a shallow copy, shallow copy, meaning he was copying the object that was originally referenced, but no longer referencing the same object address
Take a look at the example below, where B = a[:] operation to make a shallow copy, you can see, after shallow copy, A and B reference to the memory address is different
However, the reference address of the elements within A and B is the same, so be careful! It's a different!!!.
The difference between A and B's reference memory address is that the operation you do on B does not affect a.
Shallow Copy Induction:
So shallow copy, can be summed up as, copy a reference, the new object and the original object's reference is separated, but the internal element of the address reference is the same
But there are also problems with shallow copy, where is the problem? is to encounter a nested situation, such as the following situation can be seen, I gave B a copy of a a shallow copy, so that A and b of the ID (memory address) is different.
So, when I modify a[0]=8, B will not be affected because they are separate references for both A and B, but there is a nested list in the middle [4,5,6]
This [4,5,6] we can understand is that A and B also refer together, that is, for the second element of A and B, they still point to the same memory address.
In addition to say, because int is immutable type, so, the a[0] modified to 8, his reference address changed! The reference to this element is distinguished from the b[0.
Deep copy
So how to deal with such a situation? We're going to use the copy module inside the Python module.
The Copy module has 2 features
1:copy.copy (The object you want to copy): This is a shallow copy, and the previous face list [:] The operational nature is the same
2:copy.deepcopy (The object you want to copy): This is a deep copy, which, in addition to the shallow copy, will be reborn as a reference to the object, and for the internal elements, a new reference will be generated to separate it separately.
Look at the example below, when you assign B a deep copy of a, they can be said to be completely independent, whether you modify the immutable elements in a, or modify a nested variable elements, the result will not affect the B
My understanding is that deep copy can be called a recursive copy, and he will copy all of the nested mutable elements and then quote them independently.
Deep Copy Induction:
The effect of deep copy, in addition to the same as shallow copy, the object of the reference to the new into a reference, the interior of all the nested elements, he will help you open one by one independent.
I drew 2 graphs to show the difference between shallow copy and deep copy.
It should be noted that, although the reference address of the immutable elements in the list is the same after a shallow copy, however, because they are immutable elements, any immutable elements are changed, and the reference address will be new without affecting the original reference address.
Summarize
So, here, shallow copy and deep copy mechanism, basically understand.
There are special circumstances to explain.
For mutable types: int, str, tuple, float, no copy of this argument, after they are modified, the reference address is changed directly, as follows
However, if there is a nested mutable type inside a mutable type, you can still use a deep copy of the
In addition, we would like to remind you that we usually use the most direct assignment (or can be said to be directly passing the reference) method, such as the following example
He points A and b two variable elements to one memory address at the same time, so any change is affected by A and b
At last
Mutable type: list, set, Dict
Non-variable type: int, str, float, tuple
Shallow copy method: [:], Copy.copy (), using Factory function (List/dir/set)
Deep Copy method: Copy.deepcopy ()
The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.