Python之深浅copy

在对列表进行操作时,就会涉及深浅copy问题,首先我们来给出一个例子
代码如下:
n1=['jack','li','lucy','elwing',['wei',24]]
n2=n1.copy()
print("刚开始两个列表的元素值:")
print(n1)
print(n2)

n1[1]='hu'
print("改变列表n1的第二个元素的值后:")
print(n1)
print(n2)

n1[4][0]='jc'
print("改变列表n1的第五个元素的第一个元素的值后:")
print(n1)
print(n2)

运行结果:


第一次改变列表n1的第二个元素值时,只有n1列表里的值被改变了,而n2列表的值并没有任何变化

第二次改变列表n1的第五个元素值时,列表n1,n2的值都发生了改变

我们来思考一下,同样是改变列表的值,为什么第一次改变和第二次改变产生的效果完全不一样呢?

我们再来看一段代码,我想看完你可能就懂了

n1=['jack','li','lucy','elwing',['wei',24]]
n2=n1.copy()
print("刚开始两个列表的元素值:")
print(n1)
print(n2)
print("输出列表n1,n2的地址值:")
print('n1:',id(n1))
print('n2:',id(n2))

n1[1]='hu'
print("改变列表n1的第二个元素的值后:")
print(n1)
print(n2)
print("输出列表n1,n2的第二个元素的地址值:")
print('n1[1]:',id(n1[1]))
print('n2[1]:',id(n2[1]))

n1[4][0]='jc'
print("改变列表n1的第五个元素的第一个元素的值后:")
print(n1)
print(n2)
print("输出列表n1,n2的第五个元素的地址值:")
print('n1[4]:',id(n1[4]))
print('n2[4]:',id(n2[4]))

运行结果:


分析一下:当我们用到copy()时,从运行结果我们可以看到,n1,n2所指的地址并不是同一个地址,我们只是把n1中的所有元素的值给了n2,所以当我们把n1的第二个元素值改变后,它只改变n1的元素的值,并不会改变n2的元素的值,这叫浅拷贝。但是,当我们改变n1的第五个元素的第一个值时,列表n2的第五个元素的第一个值也跟着被改了,这是因为这里涉及一个子列表的概念,当列表中包含子列表时,这时的赋值就是把子列表的地址给了n2的第五个元素(因为子列表这个元素的值就是一个地址),所以当我们在改变n1的子列表的元素时,这个地址的元素就改变了,因为n2的子列表也指向这个地址,所以n2的子列表中的元素也跟着改变了,这叫深拷贝。

如果这时我们直接把n1的这个子列表这一项整体改变为一个普通类型的元素,那么n2的子列表那一项就不会改变。看看这段代码

n1=['jack','li','lucy','elwing',['wei',24]]
n2=n1.copy()
n1[4]='qqq'
print("改变列表n1的第五个元素的第一个元素的值后:")
print(n1)
print(n2)

运行结果:

这样我们就可以看出n1,n2是相互独立的,只不过,他们在包含子列表时,共用了这个子列表的地址而已,如果我们改变这个元素的地址时,他们就不会相互影响了。

话说回来,如果现在列表里包含子列表,并且我们并不想改变这样的结构,但我们还要让他们两项互不干扰,这时候,就需要用到python提供的copy这个包,实现代码如下:

import copy
n1=['jack','li','lucy','elwing',['wei',24]]
n2=copy.deepcopy(n1)
n1[4][1]=20
print("改变列表n1的第五个元素的第一个元素的值后:")
print(n1)
print(n2)

运行结果:

这就是深浅拷贝的所有内容了。

注意:在新建文件时最好不要用python的关键字作为文件名!!!

我在运行最后这段代码时,结果报了这样的错误:AttributeError: module 'copy' has no attribute 'deepcopy'

出现这个错误的原因是因为我的文件名是copy.py,改名就好了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值