The difference between deep copy and shallow copy - detailed explanation of "=" assignment, copy and deepcopy

2. Detailed explanation of "=" assignment, copy and deepcopy

Be sure to remember that the difference only makes sense for complex objects (lists nested within lists)! ! ! Because for simple objects, there is no difference between them!

Fundamental:

“=" assignment does not create a new memory space, but just points the assignment variable to the same address of the original variable. It can be seen from the id that the two addresses are exactly the same.

Shallow copy will not produce an independent object. is approximately equivalent to assignment, which only copies the original data block. Put a new label. If one of the labels changes, the data block will change. Shallow copy will copy the sub-objects , If the sub-objects are modified, the copy results will also be If you modify , but if you modify the elements in the copied object, the original object will not change. (Examples follow)

deepcopy is a true copy, deep copy, the copied object is completely copied as an independent new individual, and a new space is opened up .

One sentence image explanation:

Deep and shallow copies in complex objects:

One sentence explanation of (=) equal sign copy: is equivalent to the computerA new shortcut icon has been created in a folder, the shortcut icon is always consistent with the original file. (For equal sign copy, after copying, the address reference of List is actually directly given to the variable of equal sign copy)

One sentence explanation (copy) shallow copy: Equivalent to the computerAll subfolders within a folder have new shortcut icons, put it into a new folder, so the data in the internal subfolders will change with the changes in the original file, but the icon of the overall folder will change. (For copy copy, a new memory space is actually created after copying, one is used to store the List itself, and the internal sub-object refers to the original address, so if the internal sub-object is changed, then copy The data after will also change)

One sentence explanation (deepcopy) deep copy: is equivalent toI made a backup copy of a certain folder on my computer using a USB flash drive.. So it turns out that when the files in the folder on the computer change, the files on the USB disk will not change. (For deepcopy copy, two new memory spaces are actually created after copying, one is used to store the List, and the other is used to store the sub-objects of the List)

Official explanation:


  • Shallow copy constructs a new composite object and then (to the extent possible)references to objects found in the original object Insert it.

  • A deep copy constructs a new composite object, and then,recursively inserts a copy of the object found in the original object into it a>

Professional explanation:

  • There are no complex sub-objects in the copied object, that is, there are no nested lists in the list. Changes in the original value will not affect the value of the shallow copy, and changes in the value of the shallow copy will not affect the original value. The id value of the original value is different from the original value of the shallow copy.
  • There are complex sub-objects in the copied object (for example, a sub-element in a list is a list). If you change the value of the complex sub-object (the value in the list), it will affect the value of the shallow copy.
  • forImmutable types (tuples, numbers, strings, etc.)It is a shallow copy, and the id value of the object is the same as the original value of the shallow copy.
  • forMutable types (lists, dictionaries, etc.)for deep copy

To understand the copy principle, you should first understand the Python variable storage mechanism

The unique identity of an object in Python is: The object's id (memory address), object type, object value, And deep and shallow copy The difference between assignment and = has something to do with python’s variable storage mechanism

Storage mechanism of variables in Python

Insert image description here

For specific principles, please refer to this article, which is easy to understandyyds_In-depth understanding of Python deep copy (deepcopy), shallow copy (copy), and equal sign copy

Complex objects in Python, equal sign copy, shallow copy,deepcopyInstance analysis of deep copy mechanism

1. Differences in IDs after copying among the three

Look at the following code. The initial list is or_list = [1, [2, 3]], and perform "=" copy, copy shallow copy, and deepcopy respectively.Deep copy a>

The operation is as follows

 eq_list = or_list
 sh_list = copy(or_list)
 de_list = deepcopy(or_list)

 id(or_list)= 2269079198528
 id(eq_list)= 2269079198528
 id(sh_list)= 2269076677056
 id(de_list)= 2269076677632

【explain】:

  1. For the equal sign copy, no new memory space is created, but the eq_list variable points to the same address of the or_list variable. It can be seen from the id that the two addresses are the same id(or_list)= 2269079198528 and id(eq_list)= 2269079198528

  2. For copy copy, a new memory space is created and the sh_list variable points to the new address. The new address at this time is id(sh_list) = 2269076677056, but the memory space of the internal element is the same as before. just creates a shortcut for the internal element.

  3. For deepcopy copy, a new memory space is also created, and the entire List also points to the new address. The new address at this time is id(de_list)= 2269076677632

2. View the id values ​​at different positions in the List

Then use the id to see what is stored in the internal location of the List. You can see that there are differences in different operations and different locations.

5.  ======列表第一个位置的ID值=======  
    id(or_list[0]) = 2269075013872
    id(eq_list[0]) = 2269075013872
    id(sh_list[0]) = 2269075013872
    id(de_list[0]) = 2269075013872

6.  ======列表第二个位置的ID值===========
    id(or_list[1]) = 2269076677312
    id(eq_list[1]) = 2269076677312
    id(sh_list[1]) = 2269076677312
    id(de_list[1]) = 2269077081216

6.1 ====列表第二个位置的子列表第一位置的ID值=====
    id(or_list[1][0]) = 2269075013904
    id(eq_list[1][0]) = 2269075013904
    id(sh_list[1][0]) = 2269075013904
    id(de_list[1][0]) = 2269075013904

6.2 ====列表第二个位置的子列表第二位置的ID值=====
    id(or_list[1][1]) = 2269075013936
    id(eq_list[1][1]) = 2269075013936
    id(sh_list[1][1]) = 2269075013936
    id(de_list[1][1]) = 2269075013936

Main questions:

  1. At the or_list[0] position, all copied IDs are the same. Why?
  • Answer 1: Because for the number 1, it is a simple object, not a complex object. No matter how you copy it, they are the same.
  1. At the or_list[1] position, only the deepcopy copy is different, and the IDs of other copies remain unchanged. Why is this?
  • Answer 2: For the List[1] position, it is a complex object, so only deepcopy creates new memory, so only its id changes.
  1. Why are the IDs of or_list[1][0] and or_list[1][1] the same in all copies?
  • Answer 3: Because these two locations store simple objects, the id will not change after all copies.
  1. Why do or_list[1][1], eq_list[1][1], sh_list[1][1], de_list[1][1] have the same id?
  • Because they are all simple objects, there is no difference in ID.

Case Analysis:

import copy
a = [1,2,3,[4,5],1]
b = a
c = copy.copy(a)
d = copy.deepcopy(a)

a.append(9)
a[3].append(6)

print(a) 	#[1, 2, 3, [4, 5, 6], 1, 9]
print(b)	#[1, 2, 3, [4, 5, 6], 1, 9]   # 等号赋值二者公用一个存储空间,因此a,b变化相同
print(c)	#[1, 2, 3, [4, 5, 6], 1]  # copy赋值,内部子对象公用存储空间,因此对内部子对象的操作变化相同,但是如果对整个list操作(如a.append(),a.remove()),则变化不同。
print(d)	#[1, 2, 3, [4, 5], 1]   # deepcopy()赋值,独立开辟了一片存储空间,操作较原变量独立

print(id(a))	#4594148288
print(id(b))	#4594148288   # = 赋值 实际上将地址引用直接给新的变量
print(id(c))	#4594455328   # copy赋值,实际上新建了一个内存空间,一个用于存储List本身,内部子对象引用原来的地址
print(id(d))	#4592688496   # deepcopy()赋值 实际上新建了两个内存空间,一个用于存储List,另一个存储List的子对象,如果有更多,那么就会创建更多的内存空间


x = 'Hello World'
y = x
z = copy.copy(x)
w = copy.deepcopy(x)
# 简单对象没有区别
print(id(x)) #4617118576
print(id(y)) #4617118576
print(id(z)) #4617118576
print(id(w)) #4617118576

Extension – Deep and shallow copy in C++:

Shallow copyOnly copies the pointer to an object, not the object itself.The old and new objects still share the same memory (branch).

  • Shallow copy is a bit-wise copy of an object, which creates a new object that has an exact copy of the original object's property values.

  • If the attribute is a basic type, the value of the basic type is copied; if the attribute is a memory address (reference type), the memory address is copied, so if one of the objects changes the value in this address, it will affect the other object. .

Deep copy will create an identical object.The new object does not share memory with the original object,Modifying the new object will not change the original object, it is a "value" rather than a "reference" (not a branch)

  • Copy first-level object properties or array elements

  • Recursively copy object properties and array elements at all levels

  • A deep copy copies all properties and the dynamically allocated memory pointed to by the properties. A deep copy occurs when an object is copied along with the objects it references. Deep copy is slower and more expensive than shallow copy.
    Insert image description here

references:

Detailed explanation of copy and deepcopy in python

yyds_In-depth understanding of Python deep copy (deepcopy), shallow copy (copy), and equal sign copy

Guess you like

Origin blog.csdn.net/m0_63669388/article/details/132706327