小言_互联网的博客

python浅拷贝和深拷贝详解

464人阅读  评论(0)

假设有一个列表,如下:

然后呢,我打印出这四个列表的内存地址:

l = [1, 2, 3, 4, [1, 2, 3] ]                                   id(l)                      --------------->     1631063137352        

new_l = l                                                        id(new_l)              --------------->     1631063137352

copy_l = copy.copy(l)                                     id(copy_l)             --------------->     1631063137416

deepcopy_l = copy.deepcopy(l)                     id(deepcopy_l)     --------------->     1631063026632

可以看到,使用copy这个模块创建的浅拷贝和深拷贝在内存中都有一个新的内存空间。

进一步查看四个列表中不可变类型的id值:

l = [1, 2, 3, 4, [1, 2, 3] ]                                   id(l[1])                      --------------->     1400022144       

new_l = l                                                        id(new_l[1])              --------------->     1400022144

copy_l = copy.copy(l)                                     id(copy_l[1])             --------------->     1400022144

deepcopy_l = copy.deepcopy(l)                     id(deepcopy_l[1])     --------------->     1400022144

再查看可变类型的id值:

l = [1, 2, 3, 4, [1, 2, 3] ]                                   id(l[-1])                      --------------->     1631063137544       

new_l = l                                                        id(new_l[-1])              --------------->     1631063137544

copy_l = copy.copy(l)                                     id(copy_l[-1])             --------------->     1631063137544

deepcopy_l = copy.deepcopy(l)                     id(deepcopy_l[-1])     --------------->     1631063186312
————————————————
版权声明:本文为CSDN博主「StartFromToday」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/w494675608/article/details/82114798

 

#encoding=utf-8

import copy
a=[1,2,3,4,5,['a','b']]
#原始对象
b=a#赋值,传对象的引用
c=copy.copy(a)#对象拷贝,浅拷贝
d=copy.deepcopy(a)#对象拷贝,深拷贝
print "a=",a,"    id(a)=",id(a),"id(a[5])=",id(a[5])
print "b=",b,"    id(b)=",id(b),"id(b[5])=",id(b[5])
print "c=",c,"    id(c)=",id(c),"id(c[5])=",id(c[5])
print "d=",d,"    id(d)=",id(d),"id(d[5])=",id(d[5])
print "*"*70

a.append(6)#修改对象a
a[5].append('c')#修改对象a中的['a','b']数组对象
print "a=",a,"    id(a)=",id(a),"id(a[5])=",id(a[5])
print "b=",b,"    id(b)=",id(b),"id(b[5])=",id(b[5])
print "c=",c,"       id(c)=",id(c),"id(c[5])=",id(c[5])
print "d=",d,"            id(d)=",id(d),"id(d[5])=",id(d[5])

结果:
 

从程序的结果来看,列表a和b是赋值操作,两个对象完全指向同一个地址,a和b就是同一块地址的两个引用,其实就是一个东西,所以一个对象在修改浅层元素(不可变)或深层元素(可变)时,另一个对象也同时在变;

c是a进行浅拷贝生成的对象,可以看到a(或b)和c两个对象整体的id是不同的,但是里面的第5个元素-列表的地址却是相同的(指向同一个地址),所以b在浅层次元素层面(不可变)增加一个元素时,c并没跟着增加,但是b的第5个元素-列表在增加一个元素时,c的第5个元素也跟着增加了,这就是因为b和c的第5个元素-列表是指向同一个地址的,这个地址上的值变了,在两个地方会同时改变;

再看d,d的浅层次元素(不可变)和 深层次元素(可变)的地址和a,b,c都不一样,所以,a,b,c无论怎么修改,d都不会跟着改变,这就是深拷贝的结果。

 

原文链接:https://www.cnblogs.com/xiaxiaoxu/p/9742452.html

 

l[::-1]   结果应该是 [[1, 2, 3], 4, 3, 2, 1]

list[indexStart: indexEnd: step], 当step>0的时候,正向取值, 也就是从左往右取值,当step<0时,逆向取值。所以l[::-1]都是取的列表的逆序表, 也就是从右往左取值。

分片操作其实就是按照一定的顺序访问序列中某一范围内的元素,记住一点就行了,那就是在一定的访问顺序中,indexStart所对应的元素必须先于indexEnd所对应的元素被访问到,否则,分片操作返回的就是空的序列;而访问元素的顺序由step决定是从左往右,还是从右往左。

因此,l[0: -1: -1]是取不到值得。step < 0 ,从右往左访问数据, 先访问到得是indexEnd,再访问到indexStart。因此取到得得列表是空列表。
————————————————
版权声明:本文为CSDN博主「StartFromToday」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/w494675608/article/details/82114798


转载:https://blog.csdn.net/AIpush/article/details/102595709
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场