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()函数:
- 如果拷贝的对象是个可变的则只对第一层深拷贝,
- 如果拷贝的对象是个不可变的(比如:元组)则进行浅拷贝
实例
#!/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]