Python浅拷贝与深拷贝的区别

Python浅拷贝与深拷贝的区别一 浅拷贝浅 copy 是把原列表第一层的内存地址不加区分完全 copy 一份给新列表 list1 狄仁杰 18 1 2 注意 list2 list1 这不叫拷贝 只能说 list2 与 list1 指向了相同的内存地址 go gt gt gt list1 狄仁杰 18 1 2 gt gt gt list2 list1 copy 浅拷贝 gt gt gt print id list1 16 amp


一、浅拷贝

浅copy:是把原列表第一层的内存地址不加区分(不区分可变类型还是不可变类型)完全copy一份给新列表。
不可变类型:值发生改变时,内存地址也发生改变,即id也变,证明是没有在改变原值,是产生了新的值,如字符串,整形,浮点型,元组。
可变数据类型:值发生改变时,内存地址不变,即id不变,证明在改变原值,如列表,字典,集合。

list1=[ '狄仁杰', 18, [1,2] ] 

注意 list2 =list1 这不叫拷贝,只能说list2与list1 指向了相同的内存地址

 ```go >>> list1=["狄仁杰",18,[1,2]] >>> list2=list1.copy() # 浅拷贝 >>> print(id(list1)) 16 >>> print(id(list2)) 44 >>> >>> print(id(list1[0]),id(list1[1]),id(list1[2])) 76 9328 20 >>> print(id(list2[0]),id(list2[1]),id(list2[2])) 76 9328 20 >>> # 可见浅拷贝只拷贝第一层的内存地址,第一层的内存地址与旧列表指向相同的内存空间 

修改操作对浅拷贝的影响:

list1=[ '狄仁杰', 18, [1,2] ] list2=list1.copy() >>> list1[0]="孙尚香" >>> list1[2][0]=333 # 修改嵌套列表第一个元素 >>> list1[2][1]="张良" # 修改嵌套列表第二个元素 > >>> list1 ['孙尚香', 18, [333, '张良']] >>> list2 ['狄仁杰', 18, [333, '张良']] >>> 

在这里插入图片描述

1.对于不可变类型新的赋值,都是产生了新值,让原列表的索引指向新的内存地址,并不会影响新列表。
2.对于可变类型,我们可以改变可变类型中包含的值,但内存地址不变, 即原列表的索引指向仍然指向原来的内存地址,于是新列表也跟着一起受影响`

list1=["狄仁杰",18,[1,2]] list2=list1.copy() list1[2][0]=111 list1[2][1]=222 print(list1) # ['egon', 'lxx', [111, 222]] print(list3) # ['egon', 'lxx', [111, 222]] 

二、深拷贝

要想copy得到的新列表与原列表的改操作完全独立开必须有一种可以区分开可变类型与不可变类型的copy机制,这就是深copy

>>> list1=["狄仁杰",18,[1,2]] >>> import copy >>> list4=copy.deepcopy(list1) >>> list1 ["狄仁杰",18,[1,2]] >>> list4 ['狄仁杰', 18, [1,2]] >>> hex(id(list1)) # list1的内存地址 '0x1adae' >>> hex(id(list4)) # list4的内存地址 '0x1adae2284c0' # 不可变 不可变 可变 print(hex(id(list1[0])), hex(id(list1[1])), hex(id(list1[2]))) print(hex(id(list3[0])), hex(id(list3[1])), hex(id(list3[2]))) ''' 0x1adae1cb090 0x7ffe4f8508c0 0x1adae0e0e40 0x1adae1cb090 0x7ffe4f8508c0 0x20aa32ad6c0 ''' 可见,对于不可变类型,深拷贝的列表地址指向与原列表相同,对于可变类型,深拷贝会重新开辟内存空间 

修改操作对深拷贝的影响:

>>> list1=['狄仁杰',18,[1,2]] >>> import copy >>> list4=copy.deepcopy(list1) # 深拷贝 >>> list1 ['狄仁杰',18,[1,2]] >>> list4 ['狄仁杰',18,[1,2]] >>> list1[0]="孙尚香" # 修改list1 0号元素 >>> list1[2][0]=333 # 修改list1 2号元素即嵌套列表的0号元素 >>> list1[2][1]="张良" # 修改list1 2号元素即嵌套列表的1号元素 >>> list1 ['孙尚香', 18, [333, '张良']] >>> list4 ['狄仁杰', 18, [1, 2]] >>> >>>> hex(id(list1[2][0])) '0x274a2de79d0' >>> hex(id(list1[2][1])) '0x274a2f25d50' 可见修改list1后并没有影响到list4 

在这里插入图片描述
不可变类型(字符串、元组)没有浅拷贝(因为压根就没有改的必要),有深拷贝。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/234031.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号