Python下的深拷贝、浅拷贝和赋值

最近刷题时遇到关于拷贝的题。特别是在递归这种类型的问题是很容易踩坑。所以把这个总结下来。

修改不可变对象(str、tuple等)需要开辟新的空间
修改可变对象(list等)不需要开辟新的空间

import copy
>>> a = [1, 2, 3, ['a', 'b', 'c']]
>>> b = a                   #赋值
>>> c = copy.copy(a)        #浅拷贝
>>> d = copy.deepcopy(a)    #深拷贝

#对a进行改变
>>> a.append(4)
>>> a[3].append('d')


>>> a
[1, 2, 3, ['a', 'b', 'c', 'd'], 4]
>>> b
[1, 2, 3, ['a', 'b', 'c', 'd'], 4]    #赋值的b与a有同样的改变
>>> c
[1, 2, 3, ['a', 'b', 'c', 'd']]       #浅拷贝对于可变对象a[3](list)与a保持一致,但是append的'4'并没有拷贝
>>> d
[1, 2, 3, ['a', 'b', 'c']]            #深拷贝与之前的a一致。

#各个变量的id,能反映拷贝的内容
>>> [id(i) for i in a]
[2012045536, 2012045568, 2012045600, 2570609164680, 2012045632]
>>> [id(i) for i in b]
[2012045536, 2012045568, 2012045600, 2570609164680, 2012045632]
>>> [id(i) for i in c]
[2012045536, 2012045568, 2012045600, 2570609164680]
>>> [id(i) for i in d]
[2012045536, 2012045568, 2012045600, 2570609153416]

总结:

1.浅拷贝是在另一块地址中创建一个新的变量或容器,但是容器内的元素的地址均是源对象的元素的地址的拷贝。也就是说新的容器中指向了旧的元素( 新瓶装旧酒 )。
2.深拷贝是在另一块地址中创建一个新的变量或容器,同时容器内的元素的地址也是新开辟的,仅仅是值相同而已,是完全的副本。也就是说( 新瓶装新酒 )。
3.赋值是将一个对象的地址赋值给一个变量,让变量指向该地址( 旧瓶装旧酒 )

猜你喜欢

转载自blog.csdn.net/lisa_ren_123/article/details/80708547