Python——copy/deepcopy

Shallow Copy

浅复制,也就是copy,指的是创建一个对象以指向原有对象中各元素的地址。

>>> from copy import copy, deepcopy
>>> old_instance = ['copyme', [1, 2, 3]]
>>> new_instance = copy(old_instance)
>>> [id(i) for i in old_instance]
[48374208, 48698272]
>>> [id(i) for i in new_instance]
[48374208, 48698272]

可以看到,我们创建了一个new_instance来接收浅复制返回的old_instance,其new_instance中各元素的地址与old_instance中对应元素相同。

当我们试图修改old_instance中可变元素的值时,会相应地反映在new_instance中:

>>> old_instance[1][0] = 4
>>> old_instance
['copyme', [4, 2, 3]]
>>> new_instance
['copyme', [4, 2, 3]]

 请注意字符串和元组是不可变元素!当我们试图修改字符串时,必然会引发异常:

>>> old_instance[0][4:] = ''
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment

但我们可以将这个元素的地址指向其他字符串对象,以达到”修改“字符串的目的:

>>> old_instance[0] = 'copyyou'
>>> old_instance
['copyyou', [4, 2, 3]]
>>> new_instance
['copyme', [4, 2, 3]]

明显地可以观察到,new_instance[0]仍然指向原来字符串的地址,并没有跟随着old_instance[0]指向新的字符串对象,这是因为我们将[0]元素的地址指向了新的字符串对象,而非在原地址上修改对象。故上述修改添加引号。可自行使用id函数检查地址变化。

请注意这点特性!

 Deep Copy

深复制,将要复制的对象复制到其他内存地址上,实际上是创建一个副本,对原有对象的变动不会影响到副本。

>>> old_instance = ['copyme', [1, 2, 3]]
>>> new_instance = deepcopy(old_instance)
>>> new_instance
['copyme', [1, 2, 3]]
>>> [id(x) for x in old_instance]
[48374208, 48699232]
>>> [id(x) for x in new_instance]
[48374208, 48699152]

 可以看到,嵌套列表中的内层列表的地址已经不同。而字符串的地址相同,这是因为字符串是不可变对象,没有必要为其再开辟新的地址空间存储一份副本。

深复制的新对象在新地址不跟随原对象在原地址的变动:

>>> old_instance[1][0] = 4
>>> old_instance
['copyme', [4, 2, 3]]
>>> new_instance
['copyme', [1, 2, 3]]

也适用于嵌套结构:

>>> inner = [6, 6, 6]
>>> old_instance = [9, 9, 9, inner]
>>> new_instance = deepcopy(old_instance)
>>> old_instance
[9, 9, 9, [6, 6, 6]]
>>> new_instance
[9, 9, 9, [6, 6, 6]]
>>> [id(x) for x in old_instance]
[1507470608, 1507470608, 1507470608, 48736096]
>>> [id(x) for x in new_instance]
[1507470608, 1507470608, 1507470608, 48699032]
>>> inner[0] = 9
>>> old_instance
[9, 9, 9, [9, 6, 6]]
>>> new_instance
[9, 9, 9, [6, 6, 6]]

发布了15 篇原创文章 · 获赞 3 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/Christopher_L1n/article/details/86766088