python列表的深拷贝与浅拷贝

在python中的数据类型可以分为两大类:

1. 简单数据类型
(1) bool
(2) int
(3) float
(4) str
2. 复杂数据类型
(1)list
(2)tuple
(3)set
(4)dict
那么对于简单数据类型变量python在内存中是如何保存的呢?

str="hello world"
str_x=str
print(id(str))
print(id(str_x))

'''
运行结果:
2624680986672
2624680986672
'''

那么内存图就是这样的:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191210093909335.png
可以看到str赋值给str_x,存在str_x中的是和str一样的内存地址,str跟str_x指向了同一个内存地址,这是为了节省内存,采用的引用。

在这里插入图片描述
可以看到new hello world一个新值赋值给str,取消之前的内存地址,进行垃圾回收,这是因为,创建变量并且是新变量,就创建新的地址,再将内存地址赋值给变量。
那么复杂的数据类型在python中该如何保存呢?

x=1
print(id(x))
y=2
print(id(y))
z=3
print(id(z))
print("----------------")
str=[x,y,z]
print(str)
print(id(str))
print("----------------")
print(id(str[0]))
print(id(str[1]))
print(id(str[2]))

'''
运行结果:
1931042976
1931043008
1931043040
----------------
[1, 2, 3]
2343440058440
----------------
1931042976
1931043008
1931043040
'''

那么内存图就是这样:
在这里插入图片描述
列表中保存的实际上是x,y,z的引用地址。
上面这些都理解了就可以理解什么是浅拷贝,什么是深拷贝?

用copy()进行浅拷贝(或者copy.copy()也可以):

#浅层拷贝
list=["hello","hellow","hi"]
list1=["name","age"]
list.append(list1)
print(list)
#拷贝
list2=list.copy()
print(list2)

list.append("area")
print(list)
print(list2)

list1.clear()
print(list)
print(list2)

'''
运行结果:
['hello', 'hellow', 'hi', ['name', 'age']]
['hello', 'hellow', 'hi', ['name', 'age']]
['hello', 'hellow', 'hi', ['name', 'age'], 'area']
['hello', 'hellow', 'hi', ['name', 'age']]
['hello', 'hellow', 'hi', [], 'area']
['hello', 'hellow', 'hi', []]
'''

分析:拷贝后,向list里增加area,假设浅拷贝是引用的是地址!可以看到list里面成功了,但list1里面却没有成功,说明假设不成立,是开辟的新地址。继续往下看,我们清除了list1的内容,list跟list2中的内嵌列表都一样变成空的。可以得出结论,内嵌列表是引用地址。
结论
对于浅copy来说,第一层创建的是新的内存地址,而从第二层开始,拷贝的都是内存地址,是引用。

运用copy.deepcopy()进行深拷贝:

#深层拷贝
import copy
list=["hello","hellow","hi"]
list1=["name","age"]
list.append(list1)
print(list)
#拷贝
list2=copy.deepcopy(list)
print(list2)

list.append("area")
print(list)
print(list2)

list1.clear()
print(list)
print(list2)

'''
运行结果:
['hello', 'hellow', 'hi', ['name', 'age']]
['hello', 'hellow', 'hi', ['name', 'age']]
['hello', 'hellow', 'hi', ['name', 'age'], 'area']
['hello', 'hellow', 'hi', ['name', 'age']]
['hello', 'hellow', 'hi', [], 'area']
['hello', 'hellow', 'hi', ['name', 'age']]
'''

分析:
可以看到添加area跟清空list列表都对深层拷贝的list2无效,这是因为深层拷贝不仅第一层重新分配了内存地址,内嵌套的可变数据类型都重新开辟一块内存空间。
结论:深拷贝,对所有东西进行递归拷贝,并全部重新分配了存储空间。

来一波,推送吧!
群号:781121386
群名:人生苦短,我学编程
欢迎大家加入我们,一起交流技术!!!

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值