The difference between python assignment shallow copy and deep copy

everything in python is an object

One: assignment

First look at the following example, id View the address of the object

x = 666
id(x)  # 2650482715088
y = x
id(y)  # 2650482715088

Because y=x just points y to the object pointed to by x, then you may be curious, if you modify x, will y change together? In fact, it will not, because when you modify x, you actually create a new object and point x to this object

x = 666
id(x)  # 2650482966608
y = x
id(y)  # 2650482966608
x=x+1
id(x)  # 2650482967344
id(y)  # 2650482966608
print(y)  # 666

But this is only for immutable objects (int, string, etc.) mutable objects (list, etc.) will change. Because when an immutable object changes, a new object is actually created and assigned

x=[1,2,3]
y=x
id(x)  # 2650483005960
id(y)  # 2650483005960
x.append(5)
id(x)  # 2650483005960
id(y)  # 2650483005960
print(x)  # [1, 2, 3, 5]
print(y)  # [1, 2, 3, 5]

But if the variable object is changed explicitly, it will not affect the value of y

x = [1,2,3]
id(x)  # 2650482808648
y = x
id(y)  # 2650482808648
x = x + [4]
id(x)  # 2650482864712
print(x)
print(y)
"""
[1, 2, 3, 4]
[1, 2, 3]
"""

Because actually a new object [1,2,3,4] is created and x points to this new object

2 cache pool

Look at the following example again, x and y point to the same object

x = 666
y = x
id(x)  #  2040304935632
id(y)  #  2040304935632

And the following is different

a = 888
id(a)  # 2650482715440
b = 888
id(b)  # 2650482715568

Because two objects are created and assigned to a and b respectively

  • The first time: just create an integer object in memory 666, xand yare the tags of this integer object
  • The second time: Create two integer objects in memory , using and as labels 888respectivelyab

Note: python has a pool of small integers (-5 ~ 256)

x=2
y=2
id(x)  # 140736101317728
id(y)  # 140736101317728

For such small and commonly used integer values ​​as xand , instead of creating two objects in memory, one object is created. At this time and are both labels of integer objects . Python's small integer pool is to improve cache efficiency and reduce the frequency of frequent creation and revocation of 'commonly used' objectsypythonxy2

Similarly, strings also have a cache pool, and the cache mechanism complies with the following rules

Strings will be cached and reused, but they can only be composed of letters, numbers and underscores

s1="sssjkjksTjasdfgssshjkl哈"
len(s1)
s2="sssjkjksTjasdfgssshjkl哈"
id(s1)  # 2040304847280
id(s2)  # 2040304847664
s1 is s2  #  False
s1="sssjkjks1Tjasdfgssshjklssssssss_"
len(s1)
s2="sssjkjks1Tjasdfgssshjklssssssss_"
id(s1)  # 2040305172928
id(s2)  # 2040305172928
s1 is s2

Next is shallow copy and deep copy

shallow copy and deep copy

First review the assignment just mentioned

abc=[1,'string',['python','java',25]]
zxc=abc
id(abc)  # 2040305182344
id(zxc)  # 2040305182344

So far there may be no doubts, modify the value inside, abc, zxc will change together

abc[0]=2
abc[2].append(5)
print(abc)
print(zxc)
"""
[2, 'string', ['python', 'java', 25, 5]]
[2, 'string', ['python', 'java', 25, 5]]
"""

but pay attention

abc=[1,'string',['python','java',25]]
zxc=abc
id(abc)  
id(zxc)  
print([id(x) for x in abc])
print([id(x) for x in zxc])
"""
[140736101317696, 2042134608752, 2040305268936]
[140736101317696, 2042134608752, 2040305268936]
"""
abc[0]=2
abc[2].append(5)
print(abc)
print(zxc)
"""
[2, 'string', ['python', 'java', 25, 5]]
[2, 'string', ['python', 'java', 25, 5]]
"""
print([id(x) for x in abc])
print([id(x) for x in zxc])
"""
[140736101317728, 2042134608752, 2040305268936]
[140736101317728, 2042134608752, 2040305268936]
"""

Note: The address of abc[0] has changed here, but the address of abc[2] remains unchanged (because int is an immutable object modification means creating a new object and assigning a value, while list is a mutable object)

Please add a picture description

Next is a shallow copy

abc=[1,'string',['python','java',25]]
zxc=copy.copy(abc)
id(abc)  # 2040305143752
id(zxc)  # 2040321956104
print([id(x) for x in abc])
print([id(x) for x in zxc])
"""
[140736101317696, 2042134608752, 2040305323016]
[140736101317696, 2042134608752, 2040305323016]
"""

Note that the addresses of abc and zxc are different, but the addresses of the elements in them still point to the same address

abc[0]=2
abc[2].append(5)

print(abc)
print(zxc)
"""
[2, 'string', ['python', 'java', 25, 5]]
[1, 'string', ['python', 'java', 25, 5]]
"""
print([id(x) for x in abc])
print([id(x) for x in zxc])
"""
[140736101320832, 2042134608752, 2040305323016]
[140736101317696, 2042134608752, 2040305323016]
"""

The address of abc[0] is different from the address of zxc[0], and the value is also different
Please add a picture description

deep copy

abc=[1,'string',['python','java',25]]
zxc=copy.deepcopy(abc)
id(abc)  # 2326337710920
id(zxc)  # 2326338046664
print([id(x) for x in abc])
print([id(x) for x in zxc])
"""
[140736246742080, 2326022994736, 2326340682056]
[140736246742080, 2326022994736, 2326340706824]
"""
abc[0]=99
abc[2].append(5)
print(abc)
print(zxc)
"""
[99, 'string', ['python', 'java', 25, 5]]
[1, 'string', ['python', 'java', 25]]
"""
print([id(x) for x in abc])
print([id(x) for x in zxc])
"""
[140736246745216, 2326022994736, 2326340682056]
[140736246742080, 2326022994736, 2326340706824]
"""

insert image description here

Note: There is no such thing as a copy for non-container types (such as numbers, strings, and other 'atomic' types of objects)

Summarize:

When "abc=zxc" is assigned, no new memory space is opened, and all variable modifications will affect each other

Shallow copy: Modifications to abc immutable objects will not affect zxc, but modifications to mutable objects will affect zxc

Deep copy: the modification of all variables will not affect each other

The case of shallow copy:

1 slice zxc=abc[:]

2 copy.copy

The case of deep copy:

1 copy.deepcopy

2 DataFrame.copy()

References:
1 Diagram of the difference between assignment, shallow copy, and deep copy in python
2 Python: Are function parameters passed by value or by reference?
3 Mutable objects and immutable objects

Guess you like

Origin blog.csdn.net/m0_52118763/article/details/124771251