Introduction to Python's shallow copy, deep copy, and reference mechanism, and introduction to python's Reference Mechanism
I encountered some problems this week and realized that if the basic knowledge has not been consolidated for a period of time, I still need to review it. Here I will take a note and record it.
Prefix
First, briefly describe the problem encountered. The requirement is to write two print results.
As you can see, a points to a list object. In Python, such a value assignment statement actually means that a points to the memory address of the list and can be seen as a pointer-like concept.
B, note that it wraps a object into a list and times it by 5, so B should look like a large list with all elements in
When object a performs the append operation, the implicit meaning is that the list in the memory is modified, and all objects referenced by this object will change.
I print out the id of a and print the id of element a contained in the object B at the same time. This shows that in the list of B, the id of each element, same as
We can see that the id (memory address) of object a is 10892296. Although object B wraps object a into a new list, this element references objects with the same address, can be used to explain
Then, We append a. Because list is a mutable object, its memory address has not changed. However, for all objects referenced by this address in the memory, it can be seen from the lower half of the split line of the test image above.
This leads to a review of the Python reference mechanism, shap replication, and deep replication.
Python Reference Mechanism
Reference Mechanism case 1
From the example above, we can see that the final result of python's reference transfer is that both objects reference the content in the same region in the memory.
So let's take a look at the example below in detail.
B uses A to reference the content of the address with id 17446024. the IDs of the two users (memory addresses) are the same.
Therefore, operate A [0] = 3 or A [3] through A. append (6) will modify the content in the memory (because the list is a variable object, the memory address will not change. I will talk about it later)
This is the most basic reference case (in other words, because both A and B point to the same memory address, the modified content through B can also be reflected on)
Reference Mechanism case 2
Let's look at another case.
The question seems to replace element 2 with its own list. the result may be A = [1, [, 3], 3].
But not actually !! As you can see, in the red box, there are infinite nesting in the middle
Why?
In fact, A points to the list of [2nd, 3]. In this example, only the elements of A point to the object itself, only the structure of A has changed! However, A still points to the object
We can print the id of A to see that his point is not changed !!
Let's take A look. The direction of A has not changed.
What should we do if we want to achieve the final output effect of [1, [1, 2, 3], 3?
Here, we need to use the shortest copy. The usage can be as follows:
Shortest replication and deep Replication
Light Replication
Now, let's talk about shallow copy and deep copy. The above method is actually just a small copy. shallow copy means that it copies the originally referenced object, but the same object address is no longer referenced.
As shown in the following example, B uses the B = A [:] operation to perform the shortest copy. You can see that after the shortest copy, the memory addresses referenced by A and B are already different.
However, the reference addresses of the elements inside A and B are the same. Pay attention to this! There is a difference !!!
The difference between the referenced memory address of A and B is that the operations you perform on B will not affect.
Summary:
For this reason, we can conclude that copying a reference separates the reference of the new object from the original object, but the address reference of the internal element is the same.
But there will also be problems with replication. Where is the problem? It is the case of nesting. For example, we can see that I assigned A copy of A to B, so that the id (memory address) of A and B is different.
Therefore, when I modify A [0] = 8, B will not be affected because they are independently referenced by A and B, however, there is a nested list [, 6] in the middle.
This [, 6] can be understood as: A and B are also referenced together, that is, for the second elements of A and B, they still point to the same memory address.
In addition, since int is of an unchangeable type, after A [0] is changed to 8, its reference address changes! It is separated from the reference of the element B [0.
Deep Replication
So how should we face this situation? We need to use the copy module in the python module.
The copy module has two functions.
1: copy. copy (the object you want to copy): This is a shallow copy, and the [:] operation performed on the list is of the same nature.
2: copy. deepcopy (the object you want to copy): This is a deep copy. Apart from the shallow copy, it will generate a reference to the object. In addition, it will generate a reference for internal elements, separated separately.
Let's look at the example below. When you assign B A copy of A's deep copy, they can be said to be completely independent. No matter what you modify is the immutable element in, or modify the nested variable element in A. The result does not affect B.
In my understanding, deep replication can be called recursive copy. It will copy all nested variable elements and reference them independently.
Deep replication induction:
The effect of deep replication is similar to that of shallow replication. In addition to generating a reference to an object, all nested elements in the object will be independently created.
I drew two pictures to show the difference between the effects of shallow replication and deep replication.
It should be noted that, although the reference addresses of immutable elements in the list are the same after the shortest copy, it is because they are immutable elements, after any immutable element is changed, the reference address will be new without affecting the original reference address.
Summary
So here, the mechanism of shallow replication and deep replication is basically understood.
In addition, special cases need to be noted.
For elements such as int, str, tuple, and float, the reference address is changed directly after they are modified, as shown below:
However, if there is a nested variable type inside the immutable type, you can still use the deep Replication
In addition, we should remind you that we usually use the most direct value assignment (or directly transfer the reference) method, for example, the following example.
It directs the mutable Elements a and B to a memory address at the same time. Therefore, any change affects both a and B.
Last
Variable type: list, set, dict
Unchangeable type: int, str, float, tuple
Shortest method: [:], copy. copy (), use the factory function (list/dir/set)
Deep copy method: copy. deepcopy ()
The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.