1、可变和不可变概念
可变:变量创建完后,内存内容可以改变
可变类型有:列表、字典
不可变:变量创建,内存空间一旦分配完成,就不能在改变了
不可变类型有:数字、字符串、元组
2、拷贝
python中copy模块可以实现拷贝功能
2.1、基本概念
浅拷贝
引用(地址)拷贝,并没有产生新的空间。如果拷贝的是对象,原对象和copy对象都指向同一个内存空间,只拷贝父对象,不会拷贝对象的内部的子对象。
用法:copy.copy(变量)
深拷贝
会产生新的空间,如果拷贝的是对象,原对象和copy对象都指向不同的内存空间,会拷贝对象及其子对象(会产生新的空间)
用法:copy.deepcopy(变量)
2.2、作用
- 减少内存的使用
- 做数据的清洗、修改或者入库的时候,对原数据进行复制一份,以防数据修改之后,找不到原数据。
2.3、深浅拷贝代码实现
简单可变类型的深浅拷贝
深拷贝和浅拷贝都会产生新的空间,而且保持各自的独立性
import copy
def shallowCopy():
#可变类型的浅拷也会产生新的空间,而且能够保持各自的独立性
list1 = [1, 2, 3]
print("list1=", list1, "地址=", id(list1))
list2 = copy.copy(list1)
print("list2=", list2, "地址=", id(list2))
list1.append(1)
list3 = list1
print("list3=", list3, "地址=", id(list3))
print("----------------------------------")
print("list1=", list1, "地址=", id(list1))
print("list2=", list2, "地址=", id(list2))
print("list3=", list3, "地址=", id(list3))
def deepCopy():
#可变类型的深拷贝会残生新的空间,而且能够保持各自的独立性
list1 = [1, 2, 3]
print("list1=", list1, "地址=", id(list1))
list2 = copy.deepcopy(list1)
print("list2=", list2, "地址=", id(list2))
list1.append(1)
list3 = list1
print("list3=", list3, "地址=", id(list3))
print("----------------------------------")
print("list1=", list1, "地址=", id(list1))
print("list2=", list2, "地址=", id(list2))
print("list3=", list3, "地址=", id(list3))
复杂可变类型的深浅拷贝
浅拷贝:拷贝的是顶层对象的值,子对象不会被拷贝(只是引用子对象)
深拷贝:拷贝顶层对象和对象的子对象,子对象会产生新的内存空间
import copy
def shallowCopy():
#
list1=[1,2,3]
list2=[4,5,6]
list3=[list1,list2]
print("list1=",list1,"地址=",id(list1))
print("list2=",list2,"地址=",id(list2))
print("list3=",list3,"地址=",id(list3))
print("list3[0]=",list3[0],"地址=",id(list3[0]))
print("list3[1]=",list3[1],"地址=",id(list3[1]))
list4=copy.copy(list3)
print("list4=",list4,"地址=",id(list4))
print("list4[0]=",list4[0],"地址=",id(list4[0]))
print("list4[1]=",list4[1],"地址=",id(list4[1]))
def deepCopy():
list1=[1,2,3]
list2=[4,5,6]
list3=[list1,list2]
print("list1=",list1,"地址=",id(list1))
print("list2=",list2,"地址=",id(list2))
print("list3=",list3,"地址=",id(list3))
print("list3[0]=",list3[0],"地址=",id(list3[0]))
print("list3[1]=",list3[1],"地址=",id(list3[1]))
list4=copy.deepcopy(list3)
print("list4=",list4,"地址=",id(list4))
print("list4[0]=",list4[0],"地址=",id(list4[0]))
print("list4[1]=",list4[1],"地址=",id(list4[1]))
简单不可变类型的拷贝
不可变类型:不管是深拷贝还是浅拷贝,都不会开辟新的空间,而是直接引用被拷贝数据的地址
import copy
def shallowCopy():
# 等价于 tuple2=tuple1
tuple1=(1,2,3)
print("tuple1=",tuple1,"地址=",id(tuple1))
tuple2=copy.copy(tuple1)
print("tuple2=",tuple2,"地址=",id(tuple2))
def deepCopy():
#等价于 tuple2=tuple1
tuple1 = (1, 2, 3)
print("tuple1=", tuple1, "地址=", id(tuple1))
tuple2 = copy.deepcopy(tuple1)
print("tuple2=", tuple2, "地址=", id(tuple2)
复杂不可变类型的拷贝
浅拷贝:直接引用
深拷贝:看数据具体是可变还是不可变,如果数据可变,会产生新的空间,保持数据的独立性
import copy
def shallowCopy():
list1=[1,2,3]
list2=[1,2,3]
tuple3=(list1,list2)
print("list1=", list1, "地址=", id(list1))
print("list2=", list2, "地址=", id(list2))
print("tpule3=",tuple3,"地址=",id(tuple3))
tuple4=copy.copy(tuple3)
print("tpule4=",tuple4,"地址=",id(tuple4))
print("tpule3[0]=",tuple3[0],"地址=",id(tuple3[0]))
print("tpule3[1]=",tuple3[1],"地址=",id(tuple3[1]))
print("tpule4[0]=",tuple4[0],"地址=",id(tuple4[0]))
print("tpule4[1]=",tuple4[1],"地址=",id(tuple4[1]))
def deepCopy():
list1 = [1, 2, 3]
list2 = [1, 2, 3]
tuple3=(list1,list2)
print("list1=", list1, "地址=", id(list1))
print("list2=", list2, "地址=", id(list2))
print("tpule3=",tuple3,"地址=",id(tuple3))
tuple4=copy.deepcopy(tuple3)
print("tpule4=",tuple4,"地址=",id(tuple4))
print("tpule3[0]=",tuple3[0],"地址=",id(tuple3[0]))
print("tpule3[1]=",tuple3[1],"地址=",id(tuple3[1]))
print("tpule4[0]=",tuple4[0],"地址=",id(tuple4[0]))
print("tpule4[1]=",tuple4[1],"地址=",id(tuple4[1]))
shallowCopy()
print("*"*50)
deepCopy()
切片拷贝和字典拷贝
切片拷贝:是一种浅拷贝,副本对象和对象指向同一个结果
字典拷贝是:是一种浅拷贝
dict1={"age":[1,2]}
print("dict1=",dict1,"地址=",id(dict1))
dict2=dict1.copy()
print("dict2=",dict2,"地址=",id(dict2))
print("*"*50)
dict1['age'][0]=100
#对dict1进行修改,dict2也会被修改,所以是一种浅拷贝
print("dict1=",dict1,"地址=",id(dict1))
print("dict2=",dict2,"地址=",id(dict2))