python中深,浅copy
在说深浅拷贝之前,首先先来说一下,Python的数据结构
Python的数据结构总体分为两类:一类:字符串和数字,另外一类:列表、元组、字典等
1、字符串和数字
赋值(=)、浅拷贝(copy)和深拷贝(deepcopy)其实都毫无意义,因为它们永远指向同一个内存地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
>>> import copy
>>> n1 = 123
>>> print ( id (n1)) #打印n1的内存地址
502665488
##赋值##
>>> n2 = n1
>>> print ( id (n2))
502665488
##浅拷贝##
>>> n3 = copy.copy(n1)
>>> print ( id (n3))
502665488
##深拷贝##
>>> n4 = copy.deepcopy(n1)
>>> print ( id (n4))
502665488
|
如图所示:
2、列表、元组、字典(以及其他)
对于列表、元组和字典而言,进行赋值(=)、浅拷贝(copy)、深拷贝(deepcopy)而言,其内存地址是变化不通的。
①赋值(=)
赋值只是创建一个变量,该变量指向原来的内存地址
1 2 3 4 5 |
>>> name1 = [ 'a' , 'b' ,[ 'm' , 'n' ], 'c' ]
>>> name2 = name1
#输出结果,两个内存地址是一样的
>>> print ( id (name1), ',' , id (name2))
50077256 , 50077256
|
如图所示:
②浅拷贝(copy)
浅拷贝是指在内存地址中,只拷贝出第一层的内存的地址,所以拷贝变量和被拷贝变量的内存地址是不一样的(列表、元组和字典中的copy()方法都是浅拷贝)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
>>> import copy
>>> name1 = [ 'a' , 'b' ,[ 'm' , 'n' ], 'c' ]
#浅copy
>>> name2 = copy.copy(name1)
>>> print (name1, ',' , id (name1))
[ 'a' , 'b' , [ 'm' , 'n' ], 'c' ] , 50228296
>>> print (name2, ',' , id (name2))
[ 'a' , 'b' , [ 'm' , 'n' ], 'c' ] , 50920008
#修改列表中的元素
>>> name1[ 0 ] = 'h'
>>> name1[ 2 ][ 0 ] = 'M'
>>> print (name1, ',' , id (name1))
[ 'h' , 'b' , [ 'M' , 'n' ], 'c' ] , 50228296
>>> print (name2, ',' , id (name2))
[ 'a' , 'b' , [ 'M' , 'n' ], 'c' ] , 50920008
|
如图所示:
注:因为浅拷贝只拷贝了第一层,所以拷贝的变量和被拷贝的变量的第二层的列表的内存地址是一样的。
1 2 3 4 5 6 7 8 9 10 |
>>> import copy
>>> name1 = [ 'a' , 'b' ,[ 'm' , 'n' ], 'c' ]
>>> name2 = copy.copy(name1)
>>> name1[ 0 ] = 'h'
>>> name1[ 2 ][ 0 ] = 'M'
#name1[2][0]的内存地址和name2[2][0]内存地址是一样的
>>> print (name1, id (name1), id (name1[ 2 ][ 0 ]))
[ 'h' , 'b' , [ 'M' , 'n' ], 'c' ] 50209800 13820904
>>> print (name2, id (name2), id (name2[ 2 ][ 0 ]))
[ 'a' , 'b' , [ 'M' , 'n' ], 'c' ] 50891144 13820904
|
浅拷贝的三种表现形式:
1.用copy模块中的copy方法(跟上面的一样)
2.用切片的方式:
1 2 |
>>> name1 = [ 'a' , 'b' ,[ 'm' , 'n' ], 'c' ]
>>> name2 = name1[:]
|
3.用列表自带的方法:
1 2 |
>>> name1 = [ 'a' , 'b' ,[ 'm' , 'n' ], 'c' ]
>>> name2 = name1.copy()
|
③深拷贝(deepcopy)
深拷贝是指在内存中将所有的数据重新创建一份。
注:排除最后一层,即python内部对字符串和数字的优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
>>> import copy
>>> name1 = [ 'a' , 'b' ,[ 'm' , 'n' ], 'c' ]
#深拷贝
>>> name2 = copy.deepcopy(name1)
>>> print (name1, ',' , id (name1))
[ 'a' , 'b' , [ 'm' , 'n' ], 'c' ] , 50142472
>>> print (name2, ',' , id (name2))
[ 'a' , 'b' , [ 'm' , 'n' ], 'c' ] , 50942280
>>> name1[ 0 ] = 'h'
>>> name1[ 2 ][ 0 ] = 'M'
>>> print (name1, id (name1), id (name1[ 2 ][ 0 ]))
[ 'h' , 'b' , [ 'M' , 'n' ], 'c' ] 50142472 10937320
>>> print (name2, id (name2), id (name2[ 2 ][ 0 ]))
[ 'a' , 'b' , [ 'm' , 'n' ], 'c' ] 50942280 4896280
|
如图所示:
注:因为深拷贝会拷贝到最后一层的内存地址,所以最后一层的内存地址是不同