一、浅拷贝和深拷贝的理解
浅拷贝:新开辟一块内存,只拷贝原数据的首地址,通过原数据的首地址去获取内容。(类似于建立快捷方式)
深拷贝:新开辟一块内存,将被拷贝内容全部拷贝过来(直接独立复制)
二、浅拷贝
理解:重新分配一块内存,建立新的对象,里面的元素是原对象元素的引用
list1==list2?True(元素的值一样)
list1 is list2? False(内存不一样)
1、浅拷贝的三种方法
(1)使用数据类型本身的构造器(list、set、dict)
#列表list
list1=[1,2,3]
list2=list(list1)
#set
set1=([1,2,3])
set2=set(set1)
#字典dict
dict1={1:[1,'w'],2:33}
dict2=dict(dict1)
(2)切片--可变序列(如列表)用切片操作符:
list1=[1,2,3]
list2=list1[:]
注:
① 对于不可变数据类型(元组、字符串):
- 元组 使用 tuple()和切片操作符:
- 字符串 使用 str()和切片操作符:
- 都不是浅拷贝,没有开辟新内存来存储原对象对子对象的引用
列表的切片是浅拷贝(创建新的内存空间),元组的切片是赋值(不会创建新的内存空间)
② 切片操作符不能用于字典和集合完成浅拷贝
(3).copy()函数 或者 copy.copy()
!!copy.copy()要先导入copy模块
list1=[1,2,3]
list2=list1.copy()
import copy#需要先导入copy模块
list1=[1,2,3]
list2=copy.copy(list1)
2、浅拷贝的原对象的数据改变
子变 父不变
- 即 A=copy.copy(B) B的子对象变了,A变;B的父对象变了,A不变
list1=[(1,2),3,[4,5]]
list2=list1.copy()
list1.append(31)
print(list1)#[(1, 2), 3, [4, 5], 31]
print(list2)#[(1, 2), 3, [4, 5]]
list1=[(1,2),3,[4,5]]
list2=list1.copy()
list2.append(31)
print(list1)#[(1, 2), 3, [4, 5]]
print(list2)#[(1, 2), 3, [4, 5], 31]
list1=[(1,2),3,[4,5]]
list2=list1.copy()
list1[0]+=(31,31)
print(list1)#[(1, 2,31,31), 3, [4, 5]]
print(list2)#[(1, 2), 3, [4, 5]]
list1=[(1,2),3,[4,5]]
list2=list1.copy()
list1[2]+=[31,31]
print(list1)#[(1, 2), 3, [4, 5,31,31]]
print(list2)#[(1, 2), 3, [4, 5,31,31]]
三、深拷贝.deepcopy() 或 copy.deepcopy()
深拷贝后是两份独立的数据,改变任一数据不影响另一个
import copy
list1=[[1,2],(1,2),1]
list2=copy.deepcopy(list1)
print(list2)#[[1, 2], (1, 2), 1]
list1.append('hhh')
print(list1)#[[1, 2], (1, 2), 1, 'hhh']
print(list2)#[[1, 2], (1, 2), 1]
list1=[[1,2],(1,2),1]
list2=copy.deepcopy(list1)
list1[0].append('hhh')
print(list1)#[[1, 2, 'hhh'], (1, 2), 1]
print(list2)#[[1, 2], (1, 2), 1]
list1=[[1,2],(1,2),1]
list2=copy.deepcopy(list1)
list1[1] += (111,222)
print(list1)#[[1, 2], (1, 2,111,222), 1]
print(list2)#[[1, 2], (1, 2), 1]