Python中的浅复制与深复制

首先我们引入切片的概念。

切片适用于列表、元组、字符串、range对象等类型,但作用于列表时功能最强大。可以使用切片来截取列表中的任何部分,得到一个新列表。

举几个例子:

>>> aList = [3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
>>> aList[::]                            #返回包含所有元素的新列表
[3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
>>> aList[::-1]                          #逆序的所有元素
[17, 15, 13, 11, 9, 7, 6, 5, 4, 3]
>>> aList[::2]                           #偶数位置,隔一个取一个
[3, 5, 7, 11, 15]
>>> aList[1::2]                          #奇数位置,隔一个取一个
[4, 6, 9, 13, 17]
>>> aList[3::]                           #从下标3开始的所有元素
[6, 7, 9, 11, 13, 15, 17]
>>> aList[3:6]                           #下标在[3, 6)之间的所有元素
[6, 7, 9]

 

切片返回的是浅复制。所谓浅复制,是指生成一个新的列表,并且把原列表中所选元素的引用都复制到新列表中。如果原列表中只包含整数、实数、复数等基本类型或元组、字符串这样的不可变类型的数据,一般是没有问题的。除了切片之外,“+”运算符,“*”运算符还有一些内置函数也会生成新列表。

>>> aList = [3, 5, 7]
>>> bList = aList[::]                 #切片,浅复制
>>> aList == bList                    #两个列表的元素完全一样
True
>>> aList is bList                    #但不是同一个对象
False
>>> id(aList) == id(bList)            #内存地址不一样
False
>>> bList[1] = 8                      #修改其中一个不会影响另一个
>>> bList
[3, 8, 7]
>>> aList
[3, 5, 7]

Python中的浅复制与深复制_第1张图片 

如果原列表中包含列表之类的可变数据类型,由于浅复制时只是把子列表的引用复制到新列表中,这样的话修改任何一个都会影响另外一个。

>>> aList = [3, [5], 7]        #列表aList中包含可变的列表对象
>>> bList = aList[:]           #切片
>>> bList[1].append(6)         #调用子列表的append()方法,这个方法是原地操作的
>>> bList
[3, [5, 6], 7]
>>> aList                      #aList受到影响
[3, [5, 6], 7]

Python中的浅复制与深复制_第2张图片 

 

标准库copy中的deepcopy()函数实现深复制。所谓深复制,是指对原列表中的元素进行递归,把所有的值都复制到新列表中,对嵌套的子列表不再是复制引用。新列表和原列表是互相独立,修改任何一个都不会影响另外一个。

>>> aList = [3, [5], 7]
>>> import copy
>>> bList = copy.deepcopy(aList) #深赋值,递归复制,直到遇到可哈希对象
                           #aList和bList完全独立,互相不影响
>>> aList == bList
True
>>> aList is bList
False
>>> bList[1].append(6)         #修改bList不会影响aList
>>> bList
[3, [5, 6], 7]
>>> aList
[3, [5], 7]

Python中的浅复制与深复制_第3张图片 

 

你可能感兴趣的:(python)