前言
在实际项目中,我们想修改a的数据,同时又不想影响b的数据时 ,就需要用到拷贝。拷贝分为浅拷贝和深拷贝。
接下来,我主要以代码和图片的方式来解析它们两者之间的区别。
浅拷贝:( copy.copy() )
"""
可变类型:单层列表
"""
import copy
a = [10, 20]
b = copy.copy(a)
print(a)
print(b) # a,b值一致
print(id(a))
print(id(b)) # 两个id不一致, b和a指向不一致,说明b是拷贝出来的
a[0] = 30 #改变a的数值
print(a) # [30, 20] ,a改变
print(b) # [10, 20], b不变
![](https://img.haomeiwen.com/i9551936/5f4ddbd8dc8ce529.png)
"""
可变类型:嵌套列表
"""
a = [10, 20, [30, 40]]
b = copy.copy(a)
print(a)
print(b) # a,b值一致
print(id(a))
print(id(b)) # 两个id不一致,
#嵌套列表的id是一样的
print(id(a[2]))
print(id(b[2])) # 两个id一致,说明a[2]和b[2]的指向一致
a[2][0] = 300 #更改内层数值后,ab的值还是一样
print(a) # [10, 20, [300, 40]]
print(b) # [10, 20, [300, 40]]
![](https://img.haomeiwen.com/i9551936/3e2a42031950bfbe.png)
深拷贝:(copy.deepcopy())
import copy
a = [10, 20, [40, 50]]
b = copy.deepcopy(a)
print(a)
print(b) # 两次结果一致
print(id(a))
print(id(b)) # 两次结果不一致,a和b指向不一样
print(id(a[2]))
print(id(b[2])) # 两次结果不一致,说明第三个元素的指向是拷贝出来的
a[2][0] = 30
print(a)
print(b) # 两次结果不一致,说明深层引用也被拷贝出来了
![](https://img.haomeiwen.com/i9551936/b27420186bdf3e57.png)
小结:浅拷贝与深拷贝的区别?
- 浅拷贝,对于列表来说拷贝的是第一层引用
- 深拷贝,深拷贝会拷贝列表里面的所有引用,相当与重新开辟一个内存空间。好处是:修改a里面的列表的引用的时候,不会影响b
- 对于不可变类型的数据(数字、字符串、元组),仅仅拷贝的是引用,指向原来的内存地址,所以,无论值怎么变,结果指向都一样。
- 对于列表、字典等可变类型,就如上代码演示。
注意点: 除了浅拷贝和深拷贝,还有哪些拷贝方式?
1、对于列表:可以有切片的方式进行浅拷贝: b = a[:]
2、对于列表和字典:可以用python的内置方法进行浅拷贝(列表和字典独有的方法)copy()方法 例如:
"""
第一种:切片
"""
a = [10, 20, [30, 40]]
b = a[:]
print(id(a))
print(id(b)) # 指向不一致,就是拷贝出来的
print(id(a[2]))
print(id(b[2])) # 深一层的id是一样的,说明是浅拷贝
"""
第二种:列表名.copy() 或 字典名.copy()
"""
c = a.copy()
print(id(a))
print(id(c)) # 指向不一致,就是拷贝出来的
print(id(a[2]))
print(id(c[2])) # 一致,说明是浅拷贝
网友评论