深拷贝和浅拷贝

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))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值