程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Deep and shallow copy of Python

編輯:Python

Python It's a deep and shallow copy

List of articles

  • Python It's a deep and shallow copy
      • Deep copy and shallow copy summary :
      • Shallow copy cases
        • Yes Variable data type Advanced level of shallow copy
      • Deep copy case
      • Copy in other ways
        • Split copy
        • A copy of the dictionary

Before learning the deep and shallow copy , Let's get to know Python in 6 Large standard data types , Among them is 3 Immutable data types ,3 Variable data types . Detailed explanation of standard data types

  • Immutable data types :

    • Number( integer )
    • String ( character string )
    • Tuple ( Tuples )
  • Variable data type :

    • List( list )
    • Dictionary( Dictionaries )
    • Set( aggregate )

Deep copy and shallow copy summary :

Shallow copy :(copy)

  1. For immutable types Number 、String 、Tuple, A shallow copy is simply an address point , It won't open up new address space .
  2. For variable data types List 、Dictionary 、Set, Shallow copy will open up a new address space ( It's just the top layer that opens up a new address space , The element address is the same ), Make a light copy .
  3. After light copy , Change the value of the element in the variable data type in the original object , It will also affect the values of the elements of the copied object ; Change the value of the element in the immutable data type in the original object , Only the values in the original object will change .( The operation of the copied object is the same as that of the original object )

Deep copy (deepcopy)

  1. In the deep copy , For immutable data types Number 、String 、Tuple, Deep copy is still the point of address , It won't open up new address space .
  2. For variable data types List 、Dictionary 、Set, Deep copy will open up new address space ( Both the top-level address and the element address inside will open up a new address space ), Make a deep copy .
  3. After deep copy , Change the value in the original object ( Do not distinguish between mutable and immutable types ), Only the values in the original object are affected , The copy object will not be affected ; Empathy , Change the value in the copy object ( Do not distinguish between mutable and immutable types ), Only the values in the copy object are affected , The original object is not affected .

Because the following cases are relatively long , Mainly to verify the above summary , Personal advice , Combined with the above summary , Operate the following cases by yourself , You can have a deeper understanding of deep and shallow copies .

Shallow copy cases

import copy
# Immutable data types Number String Tuple
# For immutable data types , A shallow copy is simply an address point , Will not open up new address space 
# For immutable types Number operation 
num1 = 17
num2 = copy.copy(num1)
print("num1: " + str(num1) + ' , id :' + str(id(num1))) # num1: 17 , id :1346137664
print("num2: " + str(num2) + ' , id :' + str(id(num2))) # num1: 17 , id :1346137664
# num1 and num2 All addresses are the same 
# Change the raw data num1 Only num1 be affected , Copy objects are not affected 
num1 = 55
print("num1: " + str(num1) + ' , id :' + str(id(num1))) # num1: 55 , id :1346138880
print("num2: " + str(num2) + ' , id :' + str(id(num2))) # num2: 17 , id :1346137664
# For immutable types String operation start
str1 = "hello"
str2 = copy.copy(str1)
print("str1: " + str(id(str1))) # str1: 2253301326824
print("str2: " + str(id(str2))) # str2: 2253301326824
# str1 and str2 All addresses are the same 
# For immutable types Tuple operation start
tup1 = (18,'tom')
tup2 = copy.copy(tup1)
print("tup1: " + str(id(tup1))) # tup1: 2587894715912
print("tup2: " + str(id(tup2))) # tup2: 2587894715912
# tup1 and tup2 All addresses are the same 
# Variable data type List、Dictionary、Set
# For variable data types , Shallow copy will open up new space address ( It's just the top floor that opens up new space )
# For variable types List The operation of start
list1 = [33,44]
list2 = copy.copy(list1) # list2 list Shallow copy list1 list 
print("list1 Medium is : " + str(list1) + " , The address is " + str(id(list1)))
print("list2 Medium is : " + str(list1) + " , The address is " + str(id(list2)))
# list1 Medium is : [33, 44] , The address is 2301868933192
# list2 Medium is : [33, 44] , The address is 2301868661192
# list1 and list2 The address of is not the same 
print("list1[0] The middle string is : "+ str(list1[0]) + " , The address is " + str(id(list1[0])))
print("list2[0] The middle string is : "+ str(list2[0]) + " , The address is " + str(id(list2[0])))
# list1[0] The middle string is : 33 , The address is 1346138176
# list2[0] The middle string is : 33 , The address is 1346138176
# list1[0] and list2[0] The same address 
# For variable types Dictionary The operation of start
dic1 = {
"one":"33","two":"44"}
dic2 = copy.copy(dic1)
print("dic1 The content of is : " + str(dic1) + " , The address is : " + str(id(dic1)))
print("dic2 The content of is : " + str(dic2) + " , The address is : " + str(id(dic2)))
# dic1 The content of is : {'one': '33', 'two': '44'} , The address is : 2332667211712
# dic2 The content of is : {'one': '33', 'two': '44'} , The address is : 2332667215944
# dic1 and dic2 The address of is different 
print('dic1["one"] The content of is : ' + str(dic1["one"]) + " , The address is : " + str(id(dic1["one"])))
print('dic2["one"] The content of is : ' + str(dic2["one"]) + " , The address is : " + str(id(dic2["one"])))
# dic1["one"] The content of is : 33 , The address is : 2747176712768
# dic2["one"] The content of is : 33 , The address is : 2747176712768
# dic1["one"] and dic2["one"] The same address 
# For variable types Set The operation of start
set1 = {
"ww","11"}
set2 = copy.copy(set1)
print("set1 The content of is : " + str(set1) + " , The address is : " + str(id(set1)))
print("set2 The content of is : " + str(set2) + " , The address is : " + str(id(set2)))
# set1 The content of is : {'ww', '11'} , The address is : 1787411341832
# set2 The content of is : {'ww', '11'} , The address is : 1787411342504
# set1 and set2 The address of is different 

Yes Variable data type Advanced level of shallow copy

Because the principle is the same , The following example takes the list as an example

# Yes List( list ) Advanced level of shallow copy : When modifying the list ' Variable type ' and ' Immutable type ’ After the value of 
# Shallow copy , Create a new object , And the elements in the old object Refer to the address Copy to the elements in the new object ;
# To put it simply , That's the two one. The elements in the object The shallow copy points to the same address 
import copy
list1 = [1,2]
list2 = [3,4]
num = 55
list_sum1 = [list1,list2,num] # hold list1 、list2 、num Merge to list list_sum1 in 
list_sum2 = copy.copy(list_sum1) # hold list list_sum1 Shallow copy of elements in to list list_sum2 in 
print(list_sum1) # list_sum1 The value in :[[1, 2],[3, 4],55]
print(list_sum2) # list_sum2 The value in :[[1, 2],[3, 4],55]
print("num On : " + str(num) + " , num Upper id: "+ str(id(num)))
num = 88
print("num Next : "+ str(num) +" , num Under the id: "+ str(id(num)))
# num On : 55 , num Upper id: 1346138880
# num Next : 88 , num Under the id: 1346139936
# above num The address of and Below num The address of is different 
print(" hold 88 Copy to num after , list_sum1 Element value in : " + str(list_sum1))
print(" hold 88 Copy to num after , list_sum2 Element value in : " + str(list_sum2))
# hold 88 Copy to num after , list_sum1 Element value in : [[1, 2], [3, 4], 55]
# hold 88 Copy to num after , list_sum2 Element value in : [[1, 2], [3, 4], 55]
# hold 88 Copy to num Will get a new address , At this time list_sum1 and list_sum2 The value in does not change 
# because This num and The others above num It doesn't matter anymore 
list1[0] = 10
# Modify the list list1 The index for 0 Value , Can make list_sum1 and list_sum2 in The index for 0 The values of the elements of the are changed ,
# Because the list list1 It's a mutable object .
print(" modify list1[0] The value is equal to the 10 after , list_sum1 Element value in : " + str(list_sum1))
print(" modify list1[0] The value is equal to the 10 after , list_sum2 Element value in : " + str(list_sum2))
# modify list1[0] The value is equal to the 10 after , list_sum1 Element value in : [[10, 2], [3, 4], 55]
# modify list1[0] The value is equal to the 10 after , list_sum2 Element value in : [[10, 2], [3, 4], 55]
list_sum1[0] = 12
print(" modify list1[0] The value is equal to the 10 after , list_sum1 Element value in : " + str(list_sum1))
print(" modify list1[0] The value is equal to the 10 after , list_sum1 Element value in : " + str(list_sum2))
modify list1[0] The value is equal to the 10 after , list_sum1 Element value in : [12, [3, 4], 55]
modify list1[0] The value is equal to the 10 after , list_sum1 Element value in : [[10, 2], [3, 4], 55]
import copy
list1 = [1,2]
list2 = [3,4]
num = 55
list_sum1 = [list1,list2,num] # hold list1 、list2 、num Merge to list list_sum1 in 
list_sum2 = copy.copy(list_sum1) # hold list list_sum1 Shallow copy of elements in to list list_sum2 in 
print("list_sum1 Value : " + str(list_sum1) + " , list_sum1 Of id: " + str(id(list_sum1)))
print("list_sum2 Value : " + str(list_sum2) + " , list_sum2 Of id: " + str(id(list_sum2)))
# list_sum1 Value : [[1, 2], [3, 4], 55] , list_sum1 Of id: 2750138189000
# list_sum2 Value : [[1, 2], [3, 4], 55] , list_sum2 Of id: 2750138188936
print("list_sum1[0] Value : " + str(list_sum1[0]) + " , list_sum1[0] Of id: " + str(id(list_sum1[0])))
print("list_sum2[0] Value : " + str(list_sum2[0]) + " , list_sum2[0] Of id: " + str(id(list_sum2[0])))
# list_sum1[0] Value : [1, 2] , list_sum1[0] Of id: 2028849168584
# list_sum2[0] Value : [1, 2] , list_sum2[0] Of id: 2028849168584
print("list_sum1[0][0] Value : " + str(list_sum1[0][0]) + " , list_sum1[0][0] Of id: " + str(id(list_sum1[0][0])))
print("list_sum2[0][0] Value : " + str(list_sum2[0][0]) + " , list_sum2[0][0] Of id: " + str(id(list_sum2[0][0])))
# list_sum1[0][0] Value : 1 , list_sum1[0][0] Of id: 1346137152
# list_sum2[0][0] Value : 1 , list_sum2[0][0] Of id: 1346137152
print("list_sum1[1] Value : " + str(list_sum1[1]) + " , list_sum1[1] Of id: " + str(id(list_sum1[1])))
print("list_sum2[1] Value : " + str(list_sum2[1]) + " , list_sum2[1] Of id: " + str(id(list_sum2[1])))
# list_sum1[1] Value : [3, 4] , list_sum1[1] Of id: 2589457930824
# list_sum2[1] Value : [3, 4] , list_sum2[1] Of id: 2589457930824
# As can be seen from the above examples :
# changes list_sum1 Medium Variable type , It will affect list_sum2 ; changes list_sum1 Variable types in , The same will affect list_sum1
# changes list_sum2 Medium Immutable type , It only affects lsit_sum2 own , Does not affect the list_sum1

About = Symbol , You can refer to python Basics (5): In depth understanding of python Assignment in 、 quote 、 Copy 、 Scope

Deep copy case

Due to limited space , The case of deep copy is not listed , If you are interested, you can practice by yourself in the way of shallow copy cases , The self-contained copy of the dictionary can realize deep copy , You can combine the following cases .

  1. Shallow copy , Except for the parent copy , The child elements should also be copied ( Essentially recursive shallow copy )
  2. After deep copy , All element addresses of the original object and the copied new object are different
  3. You can use fragment expressions to make deep copies
  4. The dictionary comes with copy Method can achieve deep copy
# In the deep copy , For immutable types Number String Tuple, The deep copy is still the address pointing to , No new space will be created to copy values 
# For variable types List Dictionaty Set , Deep copy will open up new space address , Copy 
# Shallow copy , Except for top-level copy , Child elements are also copied ( Essentially recursive shallow copy )
# After deep copy , All element addresses of the original object and the copy object are not the same 
# In the previous shallow copy , Child elements do not open up new space for copying 
# But in deep copy , Child elements are also copied 

Copy in other ways

Split copy

# Fragment Expression copy start
list1 = [1,2]
list2 = [3,4]
num = 55
list_sum = [list1,list2,num]
print(list_sum)
# [[1, 2], [3, 4], 55]
nlist = list_sum[:]
print(nlist)
# [[1, 2], [3, 4], 55]
print('list_sum Value : ' + str(list_sum) + ', list_sum Of id: ' + str(id(list_sum)))
# list_sum Value : [[1, 2], [3, 4], 55], list_sum Of id: 2042818430088
print('list_sum[0] Value : ' + str(list_sum[0]) + ', list_sum[0] Of id: ' + str(id(list_sum[0])))
# list_sum[0] Value : [1, 2], list_sum[0] Of id: 2042818429064
print('list_sum[1][0] Value : ' + str(list_sum[1][0]) + ', list_sum[1][0] Of id: ' + str(id(list_sum[1][0])))
# list_sum[1][0] Value : 3, list_sum[1][0] Of id: 1346137216
print('list_sum[2] Value : ' + str(list_sum[2]) + ', list_sum[2] Of id: ' + str(id(list_sum[2])))
# list_sum[2] Value : 55, list_sum[2] Of id: 1346138880
print('nlist Value : ' + str(nlist) + ', nlist Of id: ' + str(id(nlist)))
# nlist Value : [[1, 2], [3, 4], 55], nlist Of id: 2042818430024
print('nlist[0] Value : ' + str(nlist[0]) + ', nlist[0] Of id: ' + str(id(nlist[0])))
# nlist[0] Value : [1, 2], nlist[0] Of id: 2042818429064
print('nlist[1][0] Value : ' + str(nlist[1][0]) + ', nlist[1][0] Of id: ' + str(id(nlist[1][0])))
# nlist[1][0] Value : 3, nlist[1][0] Of id: 1346137216
print('nlist[2] Value : ' + str(nlist[2]) + ', nlist[2] Of id: ' + str(id(nlist[2])))
# nlist[2] Value : 55, nlist[2] Of id: 1346138880
# A split copy is a shallow copy 

A copy of the dictionary

** The dictionary comes with copy Method can achieve deep copy **

# The dictionary comes with copy Method can be implemented start
import copy
dic0 = {
'key1':[0,1,2],'key2':10}
dic1 = dic0 # assignment 
dic2 = dic0.copy() # Shallow copy 
dic3 = copy.deepcopy(dic0) # Deep copy 
print(" It's worth it dic0 Value : " + str(dic0) + ", It's worth it dic0 Of id:" + str(id(dic0)))
# It's worth it dic0 Value : {'key1': [0, 1, 2], 'key2': 10}, It's worth it dic0 Of id:2541879095232
print(" assignment dic1 Value : " + str(dic1) + ", assignment dic1 Of id:" + str(id(dic1)))
# assignment dic1 Value : {'key1': [0, 1, 2], 'key2': 10}, assignment dic1 Of id:2541879095232
print(" Shallow copy dic2 Value : " + str(dic2) + ", Shallow copy dic2 Of id:" + str(id(dic2)))
# Shallow copy dic2 Value : {'key1': [0, 1, 2], 'key2': 10}, Shallow copy dic2 Of id:2541879099464
print(" Deep copy dic3 Value : " + str(dic3) + ", Deep copy dic2 Of id:" + str(id(dic3)))
# Deep copy dic3 Value : {'key1': [0, 1, 2], 'key2': 10}, Deep copy dic2 Of id:2541879972488
# For dictionary key( key ) The value of is of variable type 
print(" It's worth it dic0['key1'] Value : " + str(dic0['key1']) + ", It's worth it dic0['key1'] Of id:" + str(id(dic0['key1'])))
# It's worth it dic0['key1'] Value : [0, 1, 2], It's worth it dic0['key1'] Of id:2541881647240
print(" assignment dic1['key1'] Value : " + str(dic1['key1']) + ", assignment dic1['key1'] Of id:" + str(id(dic1['key1'])))
# assignment dic1['key1'] Value : [0, 1, 2], assignment dic1['key1'] Of id:2541881647240
print(" Shallow copy dic2['key1'] Value : " + str(dic2['key1']) + ", Shallow copy dic2['key1'] Of id:" + str(id(dic2['key1'])))
# Shallow copy dic2['key1'] Value : [0, 1, 2], Shallow copy dic2['key1'] Of id:2541881647240
print(" Deep copy dic3['key1'] Value : " + str(dic3['key1']) + ", Deep copy dic3['key1'] Of id:" + str(id(dic3['key1'])))
# Deep copy dic3['key1'] Value : [0, 1, 2], Deep copy dic3['key1'] Of id:2541881346568
# For dictionary key( key ) The value of is an immutable type 
print(" It's worth it dic0['key2'] Value : " + str(dic0['key2']) + ", It's worth it dic0['key2'] Of id:" + str(id(dic0['key2'])))
# It's worth it dic0['key2'] Value : 10, It's worth it dic0['key2'] Of id:1346137440
print(" assignment dic1['key2'] Value : " + str(dic1['key2']) + ", assignment dic1['key2'] Of id:" + str(id(dic1['key2'])))
# assignment dic1['key2'] Value : 10, assignment dic1['key2'] Of id:1346137440
print(" Shallow copy dic2['key2'] Value : " + str(dic2['key2']) + ", Shallow copy dic2['key2'] Of id:" + str(id(dic2['key2'])))
# Shallow copy dic2['key2'] Value : 10, Shallow copy dic2['key2'] Of id:1346137440
print(" Deep copy dic3['key2'] Value : " + str(dic3['key2']) + ", Deep copy dic3['key2'] Of id:" + str(id(dic3['key2'])))
# Deep copy dic3['key2'] Value : 10, Deep copy dic3['key2'] Of id:1346137440
# Revise the dictionary 
dic0["key1"].remove(1)
dic0["key2"] = "33"
print(" After modifying the key value ,dic0 Value : " + str(dic0) + ", After modifying the key value dic0 Of id:" + str(id(dic0)))
# After modifying the key value ,dic0 Value : {'key1': [0, 2], 'key2': '33'}, After modifying the key value dic0 Of id:2541879095232
print(" After modifying the key value , assignment dic1 Value : " + str(dic1) + ", After modifying the key value assignment dic1 Of id:" + str(id(dic1)))
# After modifying the key value , assignment dic1 Value : {'key1': [0, 2], 'key2': '33'}, After modifying the key value assignment dic1 Of id:2541879095232
print(" After modifying the key value , Shallow copy dic2 Value : " + str(dic2) + ", After modifying the key value , Shallow copy dic2 Of id:" + str(id(dic2)))
# After modifying the key value , Shallow copy dic2 Value : {'key1': [0, 2], 'key2': 10}, After modifying the key value , Shallow copy dic2 Of id:2541879099464
print(" After modifying the key value , Deep copy dic3 Value : " + str(dic3) + ", After modifying the key value , Deep copy dic2 Of id:" + str(id(dic3)))
# After modifying the key value , Deep copy dic3 Value : {'key1': [0, 1, 2], 'key2': 10}, After modifying the key value , Deep copy dic2 Of id:2541879972488
# For modifying Dictionary (key( key ) The value of is of variable type ) The situation of 
print(" After modifying the key value ,dic0['key1'] Value : " + str(dic0['key1']) + ", After modifying the key value dic0['key1'] Of id:" + str(id(dic0['key1'])))
# After modifying the key value ,dic0['key1'] Value : [0, 2], After modifying the key value dic0['key1'] Of id:2541881647240
print(" After modifying the key value , assignment dic1['key1'] Value : " + str(dic1['key1']) + ", After modifying the key value , assignment dic1['key1'] Of id:" + str(id(dic1['key1'])))
# After modifying the key value , assignment dic1['key1'] Value : [0, 2], After modifying the key value , assignment dic1['key1'] Of id:2541881647240
print(" After modifying the key value , Shallow copy dic2['key1'] Value : " + str(dic2['key1']) + ", After modifying the key value , Shallow copy dic2['key1'] Of id:" + str(id(dic2['key1'])))
# After modifying the key value , Shallow copy dic2['key1'] Value : [0, 2], After modifying the key value , Shallow copy dic2['key1'] Of id:2541881647240
print(" After modifying the key value , Deep copy dic3['key1'] Value : " + str(dic3['key1']) + ", After modifying the key value , Shallow copy dic3['key1'] Of id:" + str(id(dic3['key1'])))
# After modifying the key value , Deep copy dic3['key1'] Value : [0, 1, 2], After modifying the key value , Shallow copy dic3['key1'] Of id:2541881346568
# For modifying Dictionary (key( key ) The value of is an immutable type ) The situation of 
print(" After modifying the key value ,dic0['key2'] Value : " + str(dic0['key2']) + ", After modifying the key value dic0['key2'] Of id:" + str(id(dic0['key2'])))
# After modifying the key value ,dic0['key2'] Value : 33, After modifying the key value dic0['key2'] Of id:2541880133760
print(" After modifying the key value , assignment dic1['key2'] Value : " + str(dic1['key2']) + ", After modifying the key value , assignment dic1['key2'] Of id:" + str(id(dic1['key2'])))
# After modifying the key value ,dic0['key2'] Value : 33, After modifying the key value dic0['key2'] Of id:2541880133760
print(" After modifying the key value , Shallow copy dic2['key2'] Value : " + str(dic2['key2']) + ", After modifying the key value , Shallow copy dic2['key2'] Of id:" + str(id(dic2['key2'])))
# After modifying the key value , Shallow copy dic2['key2'] Value : 10, After modifying the key value , Shallow copy dic2['key2'] Of id:1346137440
print(" After modifying the key value , Deep copy dic3['key2'] Value : " + str(dic3['key2']) + ", After modifying the key value , Deep copy dic3['key2'] Of id:" + str(id(dic3['key2'])))
# After modifying the key value , Deep copy dic3['key2'] Value : 10, After modifying the key value , Deep copy dic3['key2'] Of id:1346137440
# in summary : The dictionary comes with copy Method can achieve deep copy 

Articles you may be interested in

  • You don't know Python in global、nonlocal What's up
  • python in break,continue,pass,else Explain in detail the usage and differences of

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved