经验拾忆(纯手工)=> 关于深拷贝/浅拷贝的代码,你,是否注意过?

列表为例(可变类型容器),直接上代码:

第一种:

a = [[1,2], [3,4]]
[_.append(666) for _ in a]        # 原生列表  (for 也是一样的,图个方便,用了推导式)
print(a)

>> [[1, 2, 666], [3, 4, 666]]

第二种:

a = [[1,2], [3,4]]
[_.append(666) for _ in a[:]]     # 新增操作: 对整个列表切片自爆
print(a)

>> [[1, 2, 666], [3, 4, 666]]

第三种:

a = [[1,2], [3,4]]
[_.append(666) for _ in copy.copy(a)]      # 新增操作: 对整个列表使用浅拷贝API
print(a)

>> [[1, 2, 666], [3, 4, 666]]

------------------ 分割线-------------------------

第四种:

a = [[1,2], [3,4]]
[_.append(666) for _ in copy.deepcopy(a)]      # 新增操作: 整个列表使用深拷贝API
print(a)

>> [[1, 2], [3, 4]]

第五种:(注意 和 第二种 对比)

a = [[1,2], [3,4]]
[_[:].append(666) for _ in a]      # 新增操作:对即将操作的子列表切片自爆
print(a)

>> [[1, 2], [3, 4]]

第六种:(注意 和 第三种 对比)

a = [[1,2], [3,4]]
[copy.copy(_).append(666) for _ in a]   # 新增操作:对即将操作的子列表 使用浅拷贝API
print(a)

>> [[1, 2], [3, 4]]

提醒0

多级容器需谨慎 (虽然多级 纯 元组是不可变类型,你想弄也弄不动它~~~)
但是这种情况,你还是需要注意:

a = ([1,2], [3,4])
# 里面的列表依然是可变的, 这算是刚入门的基础。但还应该留意

提醒一

除了 deepcopy, 其他操作都是浅拷贝。
如果你喜欢使用 [::] , [:] 这种切片拷贝, 那么更应该注意一下上述案例问题。

提醒二

也许你看上述代码很一般。甚至没有任何感觉。
但是当你把子列表当作中间值(任意操作变换), 再提醒一次 ===> 作为 中间值(或者说临时值)使用时。
你的BUG可能在向你招手!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章