Python复制方法“=/copy/deepcopy”的区别

1、当复制的值是不可变对象(数值,字符串,元组)时,=/copy/deepcopy三者没有区别。

测试代码:

import copy

a = 'abcdefgh'
b = a
c = copy.copy(a)
d = copy.deepcopy(a)

print(a,b,c,d)
print(id(a),id(b),id(c),id(d))

a += 'x'  #相当于重新赋值,把a这个标签重新贴到了一个新的箱子

print(a,b,c,d)
print(id(a),id(b),id(c),id(d))

输出结果:

abcdefgh abcdefgh abcdefgh abcdefgh
2239009875184 2239009875184 2239009875184 2239009875184
abcdefghx abcdefgh abcdefgh abcdefgh
2239007676720 2239009875184 2239009875184 2239009875184

总结:复制后,=/copy/deepcopy的id不变。改变原对象的内容,不会改变新对象的内容。但是,原对象的id会改变。

2、当复制的值是可变对象(列表,字典)时,当重新给原对象赋值时,=/copy/deepcopy三者没有区别。

测试代码:

import copy
a = [1,2,3,4]
b = a
c = copy.copy(a)
d = copy.deepcopy(a)

print(a,b,c,d)
print(id(a),id(b),id(c),id(d))

a = [5,6,7,8] #重新赋值,相当于把a这个标签重新贴到了一个新的箱子

print(a,b,c,d)
print(id(a),id(b),id(c),id(d))

输出结果:

[1, 2, 3, 4] [1, 2, 3, 4] [1, 2, 3, 4] [1, 2, 3, 4]
2239009923464 2239009923464 2239010021896 2239010023112
[5, 6, 7, 8] [1, 2, 3, 4] [1, 2, 3, 4] [1, 2, 3, 4]
2239008566984 2239009923464 2239010021896 2239010023112

总结:复制后,=的id不会变,copy和deepcopy的id会变。给原对象重新赋值,不会改变=/copy/deepcopy新对象的内容。但是,原对象的id会变,=/copy/deepcopy的id不变。

测试代码:

import copy
a = [1,2,3,4]
b = a
c = copy.copy(a)
d = copy.deepcopy(a)

print(a,b,c,d)
print(id(a),id(b),id(c),id(d))

a[0], a[1], a[2], a[3] = 5, 6, 7, 8  #直接在原列表上修改,相当于把有标签的箱子内容换了
 
print(a,b,c,d)
print(id(a),id(b),id(c),id(d))

输出结果:

[1, 2, 3, 4] [1, 2, 3, 4] [1, 2, 3, 4] [1, 2, 3, 4]
2239009809608 2239009809608 2239010021768 2239009849160
[5, 6, 7, 8] [5, 6, 7, 8] [1, 2, 3, 4] [1, 2, 3, 4]
2239009809608 2239009809608 2239010021768 2239009849160

总结:复制后,=的id不会变,copy和deepcopy的id会变。改变原对象的内容,=的新对象随之改变,但copy/deepcopy新对象的内容不会改变。原对象和=/copy/deepcopy的id不变。

3、当复制的值是可变对象(列表,字典)时,当改变的值是不可变子对象时,=/copy/deepcopy三者有区别。

测试代码:

import copy
a = [1,2,3,4]
b = a
c = copy.copy(a)
d = copy.deepcopy(a)

print(a,b,c,d)
print(id(a),id(b),id(c),id(d))

a.append(5)  #不是重新赋值,是直接修改

print(a,b,c,d)
print(id(a),id(b),id(c),id(d))

输出结果:

[1, 2, 3, 4] [1, 2, 3, 4] [1, 2, 3, 4] [1, 2, 3, 4]
2239009846728 2239009846728 2239009879432 2239009964680
[1, 2, 3, 4, 5] [1, 2, 3, 4, 5] [1, 2, 3, 4] [1, 2, 3, 4]
2239009846728 2239009846728 2239009879432 2239009964680

总结:复制后,=的id不会变,改变原对象的内容,新对象的内容随之改变。复制后,copy和deepcopy的id会变,改变原对象的内容,不会改变新对象的内容。

4、当复制的值是可变对象(列表,字典)时,当改变的值是不可变子对象时,=/copy/deepcopy三者有区别。改变的值是可变子对象时,还有进一步的区别。

测试代码:

import copy
list1=[['good','bad'],1,2]
list2=list1
list3=copy.copy(list1)
list4=copy.deepcopy(list1)

print(id(list1))
print(id(list2))
print(id(list3))
print(id(list4))

list1[0].append('medium')

print(list1)
print(list2)
print(list3)
print(list4)

print(id(list1))
print(id(list2))
print(id(list3))
print(id(list4))

list1.append(3)

print(list1)
print(list2)
print(list3)
print(list4)

print(id(list1))
print(id(list2))
print(id(list3))
print(id(list4))

输出结果:

2239009790792
2239009790792
2239009790536
2239009881864
[['good', 'bad', 'medium'], 1, 2]
[['good', 'bad', 'medium'], 1, 2]
[['good', 'bad', 'medium'], 1, 2]
[['good', 'bad'], 1, 2]
2239009790792
2239009790792
2239009790536
2239009881864
[['good', 'bad', 'medium'], 1, 2, 3]
[['good', 'bad', 'medium'], 1, 2, 3]
[['good', 'bad', 'medium'], 1, 2]
[['good', 'bad'], 1, 2]
2239009790792
2239009790792
2239009790536
2239009881864

总结:复制后,=的id不会变,改变原对象的内容,新对象的内容随之改变。复制后,deepcopy的id会变,改变原对象的内容,不会改变新对象的内容。复制后,deepcopy的id会变,内容是否会变,分为两种情况:1)如果改变的内容是可变子对象,则新对象的内容随之改变;2)如果改变的内容是不可变子对象,则新对象的内容不会改变。

综上所述,有以下结论:
1、对于数值、字符串和元组,不同的复制方式没有区别,复制后,=/copy/deepcopy的id不变。改变原对象的内容,不会改变新对象的内容。
2、对于数值、字符串和元组,只能通过赋值来修改这些对象,修改后id会发生变化。对于列表和字典这些可变对象,可以通过赋值来修改这些对象,修改后id会发生变化;也可以通过直接修改对象的内容,修改后id不会发生变化。
3、deepcopy才是真正意义上的复制了一个独立的对象,复制后,id会变,内容不会随着原对象的变化而变化。
4、可以把列表和字典这些可变对象看作箱子。b=a可以理解成标签b贴到有标签a的箱子上面,所以如果重新给a赋值,就相当于把标签a贴到了一个新箱子上,a的id自然就变了,但是b的id和内容都不变。如果是直接修改a,则相当于在修改箱子的内容,所以b的id不会变,但是内容却跟着变了。
5、copy是假的复制。复制后,id会变。但是,针对列表和字典这些可变对象,其内容变化分情况:在可变子对象变化时,会随之变化;在不可变子对象变化时,不会随之变化。

详细解释参考:https://blog.csdn.net/u011630575/article/details/78604226

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中,`copy`和`deepcopy`都是用于复制对象的函数,但它们之间有一些区别。 `copy`是浅拷贝,它创建了一个新的对象,但是这个新对象仍然与原对象共享内部嵌套对象的引用。换句话说,新对象中的某些内部对象实际上是原对象中相同的对象。当你修改一个嵌套对象时,这个改变也会反映在其他拷贝中。 `deepcopy`是深拷贝,它创建了一个全新的对象,并且递归地复制原始对象及其所有嵌套对象。这意味着新对象与原对象以及其嵌套对象完全独立,对其中一个对象的任何改变都不会影响其他对象。 具体来说,`copy`只复制了原始对象的引用,而没有复制对象自身。而`deepcopy`创建了一个全新的对象,并且递归地复制所有嵌套对象。 下面是一个简单的示例来展示它们之间的区别: ```python import copy # 原始列表 original_list = [[1, 2, 3], [4, 5, 6]] # 浅拷贝 shallow_copy = copy.copy(original_list) # 深拷贝 deep_copy = copy.deepcopy(original_list) # 修改原始列表的第一个元素 original_list = 10 print(original_list) # 输出: [[10, 2, 3], [4, 5, 6]] print(shallow_copy) # 输出: [[10, 2, 3], [4, 5, 6]] print(deep_copy) # 输出: [[1, 2, 3], [4, 5, 6]] ``` 在上面的示例中,原始列表被修改后,浅拷贝和原始列表都发生了改变,而深拷贝保持了不变。这是因为浅拷贝只复制了嵌套列表的引用,而深拷贝创建了一个新的嵌套列表

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值