Oh, my God! Only 5 pictures, thoroughly understand the depth of Python copy

First day of junior high school 2020-11-13 17:31:47
oh god pictures thoroughly understand

Python Deep and shallow copy of

Before we talk about depth copy , Let's review is and == The difference between .

In judging whether the objects are equal or not, we can use is and ==

• is： Compare two objects for the same reference , namely Their id Whether or not the same
• == ： Compare two objects for the same value .

id() , yes Python A built-in function , Returns the unique identification of the object , To get the memory address of the object .

as follows First , Will be an integer 1 Allocate a memory space . Variable a and b All point to this memory space （ Memory addresses are equal ）, So their id equal .

namely a is b by True

however , Is that true for all integers ？ The answer is ： No ！ Only in -25 ~ 256 Integers in the range do not reallocate memory space .

As shown below ：

because 257 Out of range , therefore id inequality , therefore a is b The returned value is False. >>> a = 257
>>> b = 257
>>> print(id(a))
20004752
>>> print(id(b))
20001312
>>> print(a is b)
False
>>> print(a == b)
True

This is done with performance in mind ,Python Yes -5 To 256 The integer of maintains an array , It's equivalent to a cache , When the value is in this range , The corresponding reference address is returned directly from the array . If it's not in this range , Will open up a new memory space .

is and == Which is more efficient ？

by comparison ,is Comparison is more efficient , Because it only needs to judge the id Whether it is the same or not .

and == Overload is required __eq__ This function , Traverse the contents of all elements in a variable , Is the comparison the same . So it's inefficient

Shallow copy Deep copy

Assign values to variables , There are two ways Direct assignment , Copy

Direct assignment is just = That's all right. . Copy is divided into shallow copy and deep copy

• Shallow copy ： The copy is a reference to the object , If the original object changes , The corresponding copy object will also change
• Deep copy ： Copy every element in the object , The copy object is no longer related to the original object , Two are separate objects

Just look at the concept above , It may not be easy for beginners to understand . Take a look at the following example

assignment

a = [1, 2, 3]
b = a
print(id(a)) # 52531048
print(id(b)) # 52531048

Defining variables a, At the same time a Assign a value to b. After printing, they found their id It's the same . The description points to the same memory address . And then modify a Value , Check out their id

a = [1, 2, 3]
b = a
print(id(a)) # 46169960
a = 0
print(a, b) # [1, 0, 3] [1, 0, 3]
print(id(a)) # 46169960
print(id(b)) # 46169960

At this time, I found the modified a and b And the beginning a The memory address is the same . in other words a and b Still pointing to that piece of memory , It's just in memory [1, 2, 3] Turned into [1, 0, 3]

Because the memory address changes every time it is executed again , At this time id(a) Value 46169960 And 52531048 It's the same

So we can judge ,b and a The quotation of is the same , When a When things change ,b It will change . Assignment is ： you a No matter how , Who are you pointing to , I b Follow who you point to .

Copy

When it comes to copying, you can't avoid mutable and immutable objects . • The variable object ： When it is necessary to change the values inside the object , Of this object id No change .

• Immutable object ： When it is necessary to change the values inside the object , Of this object id Will change .

a = [1, 2, 3]
print(id(a)) # 56082504
a.append(4)
# Modify the list a after id It hasn't changed , The variable object
print(id(a)) # 56082504
a = 'hello'
print(id(a)) # 59817760
a = a + ' world'
print(id(a)) # 57880072
# Modify string a after ,id There is a change . Immutable object
print(a) # hello world

Shallow copy

Copy the immutable object , To some extent, it's the same as assignment operation . But for multi-level nested structures , Shallow copy copies only the parent object , Do not copy internal child objects .

Use copy Modular copy.copy Make a light copy .

import copy
a = [1, 2, 3]
b = copy.copy(a)
print(id(a)) # 55755880
print(id(b)) # 55737992
a = 0
print(a, b) # [1, 0, 3] [1, 2, 3]

Generally speaking , I will now a Copy a copy and reallocate a memory space . Behind you a How to change , Then follow me b It doesn't matter . For shallow copies of lists, you can also use list(), list[:] To achieve

however ！ I mentioned earlier that for multi nested structures , We need to pay attention to

See the following example

import copy
a = [1, 2, [3, 4]]
b = copy.copy(a)
print(id(a)) # 23967528
print(id(b)) # 21738984
# change a Sub list in
a[-1].append(5)
print(a) # [1, 2, [3, 4, 5]]
print(b) # [1, 2, [3, 4, 5]] ？？ Why not [1, 2, [3, 4]] Well ？

b By a A shallow copy of . I modified a Nested list in , Find out b It has also been revised ？

If you still don't understand , Refer to the figure below .LIST It's a nested sub object , Points to another memory space . So shallow copy just copies the elements 1, 2 And child object references ！ Another situation , What if a tuple is nested ？

import copy
a = [1, 2, (3, 4)]
b = copy.copy(a)
# change a Tuples in
a[-1] += (5,)
print(a) # [1, 2, (3, 4, 5)]
print(b) # [1, 2, (3, 4)]

We found that the light copy came from b Nothing has changed . Because tuples are immutable objects . Changing the tuple will generate a new object .b The tuple reference in still points to the old tuple .

Deep copy

What about deep copy , Is to reallocate a memory space （ New object ）, Copy all the elements in the original object recursively to the new object .

stay Python in adopt copy.deepcopy() To achieve deep copy . import copy
a = [1, 2, [3, 4]]
b = copy.deepcopy(a)
print(id(a)) # 66587176
print(id(b)) # 66587688
# change a Variable objects in
a[-1].append(5)
print(a) # [1, 2, [3, 4, 5]]
print(b) # [1, 2, [3, 4]] After deep copy, the word list will not be affected by the original

Conclusion

1、 Both deep and shallow copies copy the source object , Take up different memory space

2、 If the source object has no subdirectories , The shallow copy can only copy the parent directory , Changing subdirectories affects shallow copy objects

3、 Slicing a list is essentially a shallow copy

In the history of the most complete Python Data summary （ Long term renewal ）. The children next door were crying --- Click to collect 