python=,copy,deepcopy对比分析

from copy import copy, deepcopy

a = {'0': [{'a':1}, 2, 3], '1': [4, 5, 6]}
b = a
c = copy(a)
d = deepcopy(a)

print('a 的第一层对象地址:{}'.format(id(a)))
print('b 的第一层对象地址:{}'.format(id(b)))
print('c 的第一层对象地址:{}'.format(id(c)))
print('d 的第一层对象地址:{}'.format(id(d)))
print('------------------------------')
print('a 的list1地址:{}'.format(id(a['0'])))
print('b 的list1地址:{}'.format(id(b['0'])))
print('c 的list1地址:{}'.format(id(c['0'])))
print('d 的list1地址:{}'.format(id(d['0'])))
print('------------------------------')
print('a 的list1的dict1地址:{}'.format(id(a['0'][0])))
print('b 的list1的dict1地址:{}'.format(id(b['0'][0])))
print('c 的list1的dict1地址:{}'.format(id(c['0'][0])))
print('d 的list1的dict1地址:{}'.format(id(d['0'][0])))
print('------------------------------')
print('a 的第二层不可变对象地址:{}'.format(id(a['0'][1])))
print('b 的第二层不可变对象地址:{}'.format(id(b['0'][1])))
print('c 的第二层不可变对象地址:{}'.format(id(c['0'][1])))
print('d 的第二层不可变对象地址:{}'.format(id(d['0'][1])))
print('------------------------------')
print('a 的list1的dict1的值1地址:{}'.format(id(a['0'][0]['a'])))
print('b 的list1的dict1的值1地址:{}'.format(id(b['0'][0]['a'])))
print('c 的list1的dict1的值1地址:{}'.format(id(c['0'][0]['a'])))
print('d 的list1的dict1的值1地址:{}'.format(id(d['0'][0]['a'])))

运行结果:

a 的第一层对象地址:1973729844160
b 的第一层对象地址:1973729844160
c 的第一层对象地址:1973732897600
d 的第一层对象地址:1973732900288
------------------------------
a 的list1地址:1973732826176
b 的list1地址:1973732826176
c 的list1地址:1973732826176
d 的list1地址:1973732898816
------------------------------
a 的list1的dict1地址:1973729843968
b 的list1的dict1地址:1973729843968
c 的list1的dict1地址:1973729843968
d 的list1的dict1地址:1973733008064
------------------------------
a 的第二层不可变对象地址:1973728143696
b 的第二层不可变对象地址:1973728143696
c 的第二层不可变对象地址:1973728143696
d 的第二层不可变对象地址:1973728143696
------------------------------
a 的list1的dict1的值1地址:1973728143664
b 的list1的dict1的值1地址:1973728143664
c 的list1的dict1的值1地址:1973728143664
d 的list1的dict1的值1地址:1973728143664

字典 {'0': [{'a':1}, 2, 3], '1': [4, 5, 6]} 与各变量的存储关系如图所示:
在这里插入图片描述

  • 变量存在栈里,对象存在堆里
  • 第一层字典 {'0':[], '1':[]} 的对象如dict1所示,第二层的两个列表 如list1, list2所示,第三层的字典如dict2所示。各值如最后两列所示。
  • 变量a指向dict1
  • 赋值= 是新增了一个变量,但是不新建对象,该变量指向原对象。
    故变量b指向dict1id(a)=id(b)
a 的第一层对象地址:1973729844160
b 的第一层对象地址:1973729844160
  • copy 是新增了一个变量,只会新建第一层对象。
    -故根据dict1复制新建了新对象 copy dict1,变量 c 指向 copy dict1 , id(a)!=id(c)
a 的第一层对象地址:1973729844160
c 的第一层对象地址:1973732897600

dict1copy dict1的内容完全一样,其中引用的第二层列表是不变的,故id(a['0'])=id(c['0'])

a 的list1地址:1973732826176
c 的list1地址:1973732826176
  • deepcopy 是把所有层都进行了复制新建。
    根据dict2复制新建得到了copy dict2list1复制新建得到了copy list1, dict2已经产生了新的,所以list1中的引用的地址变成了新的copy dict2,以此类推。
  • 对于不可变对象的拷贝,是不会再产生新的对象。如下示例(更深层的机制待更新):
from copy import copy, deepcopy

a = 1
b = a
c = copy(a)
d = deepcopy(a)
print('a={}'.format(a))
print('a 的第一层对象地址:{}'.format(id(a)))
print('b 的第一层对象地址:{}'.format(id(b)))
print('c 的第一层对象地址:{}'.format(id(c)))
print('d 的第一层对象地址:{}'.format(id(d)))

a = 1000
b = a
c = copy(a)
d = deepcopy(a)
print('a={}'.format(a))
print('a 的第一层对象地址:{}'.format(id(a)))
print('b 的第一层对象地址:{}'.format(id(b)))
print('c 的第一层对象地址:{}'.format(id(c)))
print('d 的第一层对象地址:{}'.format(id(d)))

a = 'x'
b = a
c = copy(a)
d = deepcopy(a)
print('a={}'.format(a))
print('a 的第一层对象地址:{}'.format(id(a)))
print('b 的第一层对象地址:{}'.format(id(b)))
print('c 的第一层对象地址:{}'.format(id(c)))
print('d 的第一层对象地址:{}'.format(id(d)))

a = 'How are you?'
b = a
c = copy(a)
d = deepcopy(a)
print('a={}'.format(a))
print('a 的第一层对象地址:{}'.format(id(a)))
print('b 的第一层对象地址:{}'.format(id(b)))
print('c 的第一层对象地址:{}'.format(id(c)))
print('d 的第一层对象地址:{}'.format(id(d)))

a = (1,'x','haha lala')
b = a
c = copy(a)
d = deepcopy(a)
print('a={}'.format(a))
print('a 的第一层对象地址:{}'.format(id(a)))
print('b 的第一层对象地址:{}'.format(id(b)))
print('c 的第一层对象地址:{}'.format(id(c)))
print('d 的第一层对象地址:{}'.format(id(d)))

打印结果 :

a=1
a 的第一层对象地址:2697732450608
b 的第一层对象地址:2697732450608
c 的第一层对象地址:2697732450608
d 的第一层对象地址:2697732450608
a=1000
a 的第一层对象地址:2697737907088
b 的第一层对象地址:2697737907088
c 的第一层对象地址:2697737907088
d 的第一层对象地址:2697737907088
a=x
a 的第一层对象地址:2697732851056
b 的第一层对象地址:2697732851056
c 的第一层对象地址:2697732851056
d 的第一层对象地址:2697732851056
a=How are you?
a 的第一层对象地址:2697737822064
b 的第一层对象地址:2697737822064
c 的第一层对象地址:2697737822064
d 的第一层对象地址:2697737822064
a=(1, 'x', 'haha lala')
a 的第一层对象地址:2330191099200
b 的第一层对象地址:2330191099200
c 的第一层对象地址:2330191099200
d 的第一层对象地址:2330191099200
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值