Python编程-深浅Copy

需求:
1、复制原列表并产生一个新的列表
2、针对修改操作,使原列表和新列表独立开,修改其中的一个列表,另一个列表不变

# 原列表
list1 = ['tom', 'alex', ['albert', 'abel', 'adam']]	
# 通过打印id,表示列表在内存中的地址
print(id(list1[0]), id(list1[1]), id(list1[2]))
print(id(list1[2][0]), id(list1[2][1]), id(list1[2][2]))

原列表在内存中的存储方式为:
列表的存储方式
  在通常情况下,复制一个列表会使用:list2 = list1,这只是赋值操作,在栈区里新创建list2变量,将list1的内存地址赋值给list2。虽然可以实现需求1,对列表的读操作没有影响;但是对于需求2,如果对list1的值做出修改,因为list2idlist1id相同,在遍历list2值的时候,读取的是list1的内存,结果将会是list1修改后的值,也就是说,对于改操作,两个列表并没有独立开。
赋值操作的内存变化

浅 Copy

  为了实现上述需求,可以调用copy()方法。

list1 = ['tom', 'alex', ['albert', 'abel', 'adam']]
list3 = list1.copy()

  而后,通过打印每个列表id探究原列表和新列表在内存中的存储方式。

print(id(list1), id(list3))
# 打印原列表各项的id
print(id(list1[0]), id(list1[1]), id(list1[2]))
print(id(list1[2][0]), id(list1[2][1]), id(list1[2][2]))
# 打印新列表各项的id
print(id(list3[0]), id(list3[1]), id(list3[2]))
print(id(list3[2][0]), id(list3[2][1]), id(list3[2][2]))

"""
打印结果:
id(list1):1898489782080;id(list3):1898489613760
# 原列表各项的id:
1898488642096 1898488642864 1898489783104
1898488332720 1898489830960 1898489831024
# 新列表各项的id:
1898488642096 1898488642864 1898489783104
1898488332720 1898489830960 1898489831024
"""

  可以简单的画出存储形式:
浅Copy的内存形式

  通过打印的id可以发现,在内存中新开辟了一个空间用来存储产生的新列表,但是从子列表的id可以发现,并没有开辟新的内存空间用来存储子列表。此时,修改原列表某一项的值。

list1[0] = 'Tom'
list1[2][0] = 'Albert'

在内存中的变化如图所示:
在这里插入图片描述

  在遍历两个列表各项的值时,明显可以发现,一级列表实现了改操作的独立,但由于没有开辟新的内存空间用以存储子列表,所以子列表的修改操作并没有独立开。

深 Copy

  要想copy得到的新列表与原列表的改操作完全独立开,必须有一种可以区分可变类型和不可变类型的copy机制。这便是深Copy
对于深Copy操作,必须要导入外部模块,再调用deepcopy()方法

import copy
list1 = ['tom', 'alex', ['albert', 'abel', 'adam']]
list4 = copy.deepcopy(list1)

  而后,通过打印每个列表id探究原列表和新列表在内存中的存储方式。

print(id(list1), id(list4))
# 打印原列表各项的id
print(id(list1[0]), id(list1[1]), id(list1[2]))
print(id(list1[2][0]), id(list1[2][1]), id(list1[2][2]))
# 打印新列表各项的id
print(id(list4[0]), id(list4[1]), id(list4[2]))
print(id(list4[2][0]), id(list4[2][1]), id(list4[2][2]))

"""
打印结果:
id(list1):2412909307776;id(list4):2412909305984
# 原列表各项的id:
2412908165680 2412908166448 2412909227456
2412907856368 2412909354800 2412909354864
# 新列表各项的id:
2412908165680 2412908166448 2412909308224
2412907856368 2412909354800 2412909354864
"""

  可以简单的画出存储形式:
深Copy的存储形式

  从存储形式中可以发现,在内存中新开辟了两块内存空间,用以存储复制产生的新列表,包括子列表。在此时,修改原列表某一项的值。

list1[0] = 'Tom'
list1[2][0] = 'Albert'

在内存中的变化为:
内存变化
  在遍历两个列表各项的值时,明显可以发现,list1某项值的改变(包括子列表中某一项的值),不会引起深Copy产生的新列表。也就是说:对于原列表和新列表,针对改操作,两个列表已经完全独立开,完全实现了两个需求。

总结

  1. 对于浅Copy:如果原列表存储的都是不可变类型,浅copy完全可以实现需求。
  2. 对于深Copy:如果原列表存储有可变类型和不可变类型,深Copy才可以实现需求
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值