Python中赋值、浅拷贝与深拷贝

时间:2021-01-14 19:48:45

Python中关于对象复制有三种类型的使用方式,赋值、浅拷贝与深拷贝。我们来看看他们之间的区别
先来看一下这段程序

>>> import copy
>>> a = [1,2,3,4,['a','b']]
>>> b = a    # a,b两者指向的是同一个内存地址
>>> c = copy.copy(a)  # 仅仅拷贝了最外层,list中的元素指向的是同一个内存地址
>>> d = copy.deepcopy(a)  # 完完全全的拷贝

>>> a.append(5)
>>> print(a)
[1, 2, 3, 4, ['a', 'b'], 5]
>>> print(b)
[1, 2, 3, 4, ['a', 'b'], 5]
>>> print(c)
[1, 2, 3, 4, ['a', 'b']]
>>> print(d)
[1, 2, 3, 4, ['a', 'b']]

>>> a[4].append('c')
>>> print(a)
[1, 2, 3, 4, ['a', 'b', 'c'], 5]
>>> print(b)
[1, 2, 3, 4, ['a', 'b', 'c'], 5]
>>> print(c)
[1, 2, 3, 4, ['a', 'b', 'c']]
>>> print(d)
[1, 2, 3, 4, ['a', 'b']]

一、赋值

在python中,对象的赋值就是简单的对象引用
list_b = list_a

这种情况下,list_b和list_a指向的是同一个内存地址,只是别名不同,所以更改list_b中的元素一定会改变list_a

二、浅拷贝(shallow copy)

浅拷贝会创建新对象,但其内容是原对象的引用。浅拷贝实质上只拷贝了原来对象的最外层、里边的各个元素还只是引用。比如[‘a’, ‘b’]就是
列表中的一个元素,当这个元素由[‘a’, ‘b’]变成了[‘a’, ‘b’,’c’], list_b因为对元素并没有进行拷贝,所以list_b也会变成[‘a’, ‘b’,’c’]

浅拷贝有三种形式:切片操作,工厂函数,copy模块中的copy函数

切片操作:

new_list = old_list[:]

工厂函数

new_list = list(old_list)

copy模块中的copy函数:

import copy
new_list = copy.copy(old_list)

三、深拷贝(deep copy

深拷贝只有一种形式,copy模块中的deepcopy函数。

和浅拷贝对应,深拷贝拷贝了对象的所有元素,包括多层嵌套的元素。因而,它的时间和空间开销要高。

同样对list_a,若使用list_b = copy.deepcopy(list_a),再修改list_b将不会影响到list_a了。即使嵌套的列表具有更深的层次,也不会产生任何影响,因为深拷贝出来的对象根本就是一个全新的对象,不再与原来的对象有任何关联。

对于浅拷贝和深拷贝的区别,下面的图看起来会很直观。我们发现浅拷贝只是拷贝出了一个新的list, 但里面的元素却没有被拷贝。
 
 
Python中赋值、浅拷贝与深拷贝

参考:

http://www.cnblogs.com/work115/p/5619541.html
————The End————