Python浅拷贝和深拷贝

Python浅拷贝和深拷贝,第1张

浅拷贝 & 深拷贝 引入

笔者在创建二维列表引发的思考!!!

# str1、str2 内容相同,C、D内容相同。str1 和 str2 指向同一个对象, 而 C 和 D 却不指向同一个!!!

>>> str1 = 'apple'        
>>> str2 = 'apple'
>>> str1 is str2
True
>>> C = [1,2,3]
>>> D = [1,2,3]
False

# 看起来是两种创建方式,可是他们一样吗???
# 法一:
>>> A = [0] * 3
>>> for i in range(3):
        A[i] = [0] * 3
        
>>> print(A)
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]

# 法二: 
>>> B = [[0] * 3] * 3
>>> print(B)
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]

# 通过下列例子我们发现!!!二者大有不同!!!
>>> A[0][1] = 3
>>> print(A)
[[0, 3, 0], [0, 0, 0], [0, 0, 0]]
>>> B[0][1] = 3
>>> print(B)
[[0, 3, 0], [0, 3, 0], [0, 3, 0]]

# 验证————分析!!!
>>> A[0] is A[2]
False
# 我们发现通过第22行代码创建的二维列表B: B[0]、B[1]、B[2]竟然指向同一个对象!!!
>>> B[0] is B[2]  
True

# 结论: 原来 通过 B = [[0] * 3] * 3 创建二维列表,只是对同一个列表的引用进行了copy,而不是对列表本身进行copy.
# 即重复引用它
浅拷贝

浅拷贝只是拷贝了外层的对象,如果包含嵌套对象那么包含的只是其引用。

>>> x = [[1,2,3],[4,5,6],[7,8,9]]
>>> y = x.copy() # 列表的copy方法
>>> x is y
False    # 拷贝了外层,所以外层对象不是同一个。(因为在内存中复制了)
>>> x[2] is y[2]
True     # 内层没有拷贝,

# 验证一下               
>>> x[1][1] = 0
>>> print(y)
[[1, 2, 3], [4, 0, 6], [7, 8, 9]]
>>> print(x)
[[1, 2, 3], [4, 0, 6], [7, 8, 9]]
>>> x[1] = [0,0,0]
>>> print(x)
[[1, 2, 3], [0, 0, 0], [7, 8, 9]]
>>> print(y)
[[1, 2, 3], [4, 0, 6], [7, 8, 9]]
>>>

>>> import copy
>>> x = [[1,2,3],[4,5,6],[7,8,9]]
>>> y = copy.copy(x)  # copy模块中的copy函数
>>> x[1][1] = 0
>>> print(y)
[[1, 2, 3], [4, 0, 6], [7, 8, 9]]
>>> x = [[1,2,3],[4,5,6],[7,8,9]]

这是为什么呢?

原来在 x = [[1,2,3],[4,5,6],[7,8,9]]中

可以看成 引用x 指向 对象1

因为对象1中又包含3个列表

so 引用 x 指向 [引用101, 引用102, 引用103]

so 最后 y 指向 x.copy 只是 拷贝了三个引用 ...

拷贝了三个引用即在存储中重新创建(copy)了3个相同引用,他们指向存储中的同一个[[1,2,3],[4,5,6],[7,8,9]]

so 修改[[1,2,3],[4,5,6],[7,8,9]] 在内存的值 ... 你懂的

深拷贝

多维列表内外层全部拷贝!!!

# 深拷贝
>>> y = copy.deepcopy(x)
>>> x[1][1] = 0
>>> print(y)
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> print(x)
[[1, 2, 3], [4, 0, 6], [7, 8, 9]]
>>>
结语

既然如此深拷贝如此方便,

python为什么要默认深拷贝呢?答案就两字————效率

 

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/916328.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存