Python中的浅拷贝与深拷贝

深拷贝与浅拷贝

浅拷贝:只拷贝了一个地址,即和原变量指向同一个地址空间

深拷贝:复制了原变脸指向空间里的内容,并开辟了新的空间

所有的等号赋值是浅拷贝

深拷贝需要用到copy模块

深拷贝举例:

import copy

a = [1, 2, 3, 4]

b = copy.deepcopy(a)
print("a == b", a == b)
print("a is b", a is b)

out:

a == b True
a is b False

几点说明:

deepcopy()函数是会递归深拷贝,即比如列表里面有列表会统统深拷贝

注意copy.copy()函数:

  1. 如果拷贝的对象是个可变的则只对第一层深拷贝,
  2. 如果拷贝的对象是个不可变的(比如:元组)则进行浅拷贝
实例
#!/usr/bin/python
# -*-coding:utf-8 -*-
 
import copy
a = [1, 2, 3, 4, ['a', 'b']] #原始对象
 
b = a                       #赋值,传对象的引用
c = copy.copy(a)            #对象拷贝,浅拷贝
d = copy.deepcopy(a)        #对象拷贝,深拷贝
 
a.append(5)                 #修改对象a
a[4].append('c')            #修改对象a中的['a', 'b']数组对象
 
print( 'a = ', a )
print( 'b = ', b )
print( 'c = ', c )
print( 'd = ', d )
以上实例执行输出结果为:

('a = ', [1, 2, 3, 4, ['a', 'b', 'c'], 5])
('b = ', [1, 2, 3, 4, ['a', 'b', 'c'], 5])
('c = ', [1, 2, 3, 4, ['a', 'b', 'c']])
('d = ', [1, 2, 3, 4, ['a', 'b']])

切片复制列表是深拷贝

In [5]: alist = [1,2,3,4]                                                                         

In [6]: blist = alist                                                                             

In [7]: id(alist)                                                                                 
Out[7]: 140069425918792

In [8]: id(blist)                                                                                 
Out[8]: 140069425918792

In [9]: clist = alist[::]                                                                         

In [10]: id(clist)                                                                                
Out[10]: 140069426299464

字典拷贝

In [38]: a = {1:[1,2]}                                                                        

In [39]: b = a.copy()                                                                         

In [40]: c = a.copy()                                                                         

In [41]: b[1].append(3)                                                                       

In [42]: a,b,c                                                                                
Out[42]: ({1: [1, 2, 3]}, {1: [1, 2, 3]}, {1: [1, 2, 3]})

In [43]: b[1].append('b')                                                                     

In [44]: a,b,c                                                                                
Out[44]: ({1: [1, 2, 3, 'b']}, {1: [1, 2, 3, 'b']}, {1: [1, 2, 3, 'b']})
    
--------------------------------------------------------------------------------------------    
In [46]: a = {1: [1,2,3]}                                                                     

In [47]: b = copy.deepcopy(a)                                                                 

In [48]: a[1].append('a')                                                                     

In [49]: a,b                                                                                  
Out[49]: ({1: [1, 2, 3, 'a']}, {1: [1, 2, 3]})

在使用列表时的一些常见误区

>>> lists = [[]] * 3
>>> lists
 [[], [], []]
>>> lists[0].append(3)
>>> lists
 [[3], [3], [3]]

具体的原因在于 [[]] 是一个包含了一个空列表的单元素列表,所以 [[]] * 3 结果中的三个元素都是对这一个空列表的引用。修改 lists 中的任何一个元素实际上都是对这一个空列表的修改。你可以用以下方式创建以不同列表为元素的列表:

>>> lists = [[] for i in range(3)]
>>> lists[0].append(3)
>>> lists[1].append(5)
>>> lists[2].append(7)
>>> lists
[[3], [5], [7]]

作为函数参数时

def add_to(num, aList=[]):
    aList.append(num)
    return aList

print(add_to(1))    # 输出 [1]
print(add_to(2))    # 输出 [1, 2]
print(add_to(3))    # 输出 [1, 2, 3]
def add_to(num, aList=[]):
    if aList:
        aList = []
    aList.append(num)
    return aList

print(add_to(1))    # 输出 [1]
print(add_to(2))    # 输出 [2]
print(add_to(3))    # 输出 [3]
posted @ 2019-10-12 22:23  KainHuck  阅读(240)  评论(0编辑  收藏  举报