python数据结构之深浅拷贝

Python中深浅拷贝详解

变量-引用-对象(可变对象,不可变对象)-切片-拷贝(浅拷贝,深拷贝)

变量:在Python中一切都是对象,比如:3,3.14,“Hello world”,【1,2,3,4】,{‘a’:1}….

输出:

甚至连Type其本身也是对象,type对象

Python中的变量指对象的引用,Python是动态类型,程序运行时会根据对象的类型来确认变量到底是什么类型

比如:a=3

其中变量a是对象3的一个引用。在程序内部,变量事实上是到对象内存空间的一个指针

https://i-blog.csdnimg.cn/blog_migrate/fa7abd93adde7e0b18d934f89835ef74.png

变量:指一个元素,拥有指向对象的连接空间

对象:被分配的一个内存,存储其所代表的值

引用:自动形成的从变量到对象的指针

共享引用:比如:

输出:

可以看出变量a和b指向了同一个对象的内存空间

可变对象:在Python中指可以修改的对象,例如:列表,字典

不可变对象:在Python中指不能改变的对象,例如:字符串、元组、数字

L1=[3,4,5,6,7,8,9]#L1变量指向一个可变对象:列表
L2=L1#将L1的值赋给L2后,两者共同引用同一个对象
L1[0]=300#将L1列表中的第一个元素改变
print(L1,L2)



输出:
#[300, 4, 5, 6, 7, 8, 9] [300, 4, 5, 6, 7, 8, 9]

可以看出改变L1之后,L2的值跟着改变了,如果不想让L2跟着改变,可以采用切片或者拷贝的方法

L1=[2,3,4,5,6,7]
L2=L1[:]#切片操作
print(id(L1),id(L2))#切片后对象就不一样了
L1[0]=200
print(L1,L2)#L1改变,L2不改变



输出:
12966968 12965408
[200, 3, 4, 5, 6, 7] [2, 3, 4, 5, 6, 7]

切片:与使用索引来访问单个元素类似,可以使用切片操作来访问一定范围内的元素。切片通过冒号隔开两个索引来实现

拷贝:切片操作可以应用在所有的序列中,例如:列表、元组、字符串,但是不能用在字典当中,对字典只能使用D.copy()方法或D.deepcopy()方法,深浅拷贝可以用在序列当中,也可以应用在字典中。

import copy

   X = copy.copy(Y)      #浅拷贝:只拷贝顶级的对象,或者说:父级对象

    X = copy.deepcopy(Y)  #深拷贝:拷贝所有对象,顶级对象及其嵌套对象。或者说:父级对象及其子对象

代码实现:

如果字典中只含有顶级对象

import copy
D={'age':20,'name':'zhangsan'}#原始字典
C1=copy.copy(D)#浅拷贝
C2=copy.deepcopy(D)#深拷贝
print(id(D),id(C1),id(C2))#三个不同对象
D['name']='lisi'#改变源字典
print(D,C1,C2)


输出:
28681296 28681728 59780144
{'age': 20, 'name': 'lisi'} {'age': 20, 'name': 'zhangsan'} {'age': 20, 'name': 'zhangsan'}
#可以看出只改变了原始字典中的对象值

如果字典中含有嵌套对象

import copy
D={'name':{'first':'zhang','last':'san'},'jobs':['IT','HR']}#原始字典含有嵌套对象
C1=copy.copy(D)#浅拷贝
C2=copy.deepcopy(D)#深拷贝
D['jobs'][0]='data'#改变原始字典中的jobs子对象‘it'变为’data'
print(D,C1,C2)



输出:
{'name': {'first': 'zhang', 'last': 'san'}, 'jobs': ['data', 'HR']} {'name': {'first': 'zhang', 'last': 'san'}, 'jobs': ['data', 'HR']} {'name': {'first': 'zhang', 'last': 'san'}, 'jobs': ['IT', 'HR']}
#可以看出浅拷贝受影响,深拷贝不受影响

结论:

深浅拷贝都是对源对象的复制,占用的是不同的内存空间

如果源对象只含一级目录,深浅拷贝不受影响

如果含多级目录,浅拷贝受影响,深拷贝不受影响

切片属于浅拷贝

=                        :地址相同;原值改变,值随之改变

copy.copy()        :可变类型(list、dict)地址不同;原值改变,值随之改变

                              不变类型(tuple)地址相同;值不可变

copy.deepcopy():地址不同;原值改变,值不随之改变

深浅拷贝的作用:
1,减少内存的使用 
2,以后在做数据的清洗、修改或者入库的时候,对原数据进行复制一份,以防数据修改之后,找不到原数据。

对于不可变对象的深浅拷贝:
不可变对象类型,没有被拷贝的说法,即便是用深拷贝,查看id的话也是一样的,如果对其重新赋值,也只是新创建一个对象,替换掉旧的而已。

一句话就是,不可变类型,不管是深拷贝还是浅拷贝,地址值和拷贝后的值都是一样的。
 

参考文献:https://blog.csdn.net/u012377333/article/details/41956727

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值