date: 2021-06-12title: Python之深浅拷贝 #标题
tags: python #标签
categories: python # 分类

整理下个人对Python的深浅拷贝的理解。

浅拷贝

浅拷贝的定义

对于浅copy来说,第一层创建的是新的内存地址,而从第二层开始,指向的都是同一个内存地址,所以,对于第二层以及更深的层数来说,保持一致性。

浅拷贝的使用

  1. print('浅拷贝')
  2. '''
  3. 浅拷贝只是拷贝了引用,并没有拷贝内容,只是两个内存地址指向的是同一个内容
  4. '''
  5. c = [[7, 8, 9], [6, 5, 4]]
  6. d = c.copy()
  7. print(id(c), c) # 输出:1925394118664 [[7, 8, 9], [6, 5, 4]]
  8. print(id(d), d) # 输出:1925394118536 [[7, 8, 9], [6, 5, 4]]
  9. c[0][1] = 0 # 此时将c这个列表进行修改,然后分别打印b、c,会发现b的内容也修改了
  10. print(id(c), c) # 输出:1925394118664 [[7, 0, 9], [6, 5, 4]]
  11. print(id(d), d) # 输出:1925394118536 [[7, 0, 9], [6, 5, 4]]
  12. '''
  13. 因为是拷贝的引用,所以在进行浅拷贝的时候,被拷贝对象的第二层改变,
  14. 拷贝对象也会改变。
  15. '''

python之深浅拷贝 - 图1

因为是引用的同一个值,所以当被拷贝,拷贝对象的值也会改变。

深拷贝

深拷贝的定义

嵌套的可变数据类型重新开辟一块新的内存空间。

深拷贝的使用

  1. print('深拷贝')
  2. import copy # 使用深拷贝需要导入copy模块
  3. a = [[1, 2, 3], [4, 5, 6]]
  4. b = copy.deepcopy(a) # 深拷贝是对于一个对象所有层次的拷贝
  5. print(id(a), a) # 输出:1604070389832 [[1, 2, 3], [4, 5, 6]]
  6. print(id(b), b) # 输出:1604070389704 [[1, 2, 3], [4, 5, 6]]
  7. a[1][1] = 9 # 对a的值进行修改
  8. print(id(a), a) # 输出: 1604070389832 [[1, 2, 3], [4, 9, 6]]
  9. print(id(b), b) # 输出:1604070389704 [[1, 2, 3], [4, 5, 6]]
  10. '''
  11. 因为开辟了新的内存空间,并且储存的是开始的被拷贝对象的值,
  12. 所以在拷贝后被拷贝对象的值改变,不会影响到拷贝对象
  13. '''

python之深浅拷贝 - 图2

深浅拷贝的区别

  • 如果用copy、copy.deepcopy对一个全部都是不可变数据类型的数据进行拷贝,那么它们的结果相同,都是引用指向;
  • 在深拷贝时,如果元素为可变的数据类型,则是创建一个新的指向,如果是不可变的数据类型,则还是指向原来的元素;
  • 基本上只要不是我们手动调用的deepcopy方法都是浅拷贝,切片拷贝字典拷贝都是浅拷贝,而有些内置函数可以生成拷贝(list),属于深拷贝:a = list(range(10))b = list(a)