标签:通过 赋值 不可变 递归循环 例子 没有 port 情况下 tab
目录
坑的编码 | 内容 |
---|---|
Py006-3 | Python3 中的深拷贝与浅拷贝 |
个人觉得深拷贝与浅拷贝里面大有文章,此篇随笔只能算是浅谈。
复合对象:包含其他对象的对象,如列表、类实例等
浅拷贝会构造一个新的复合对象,然后(在允许的前提下)向其中写入对原始对象的引用
对于可变或包含可变项的容器,有时需要一个可以在不破坏其它容器的情况下更改自身的副本。
# 例1 从对象的地址上看
list1_1 = [1, 2, 3, 4, 5]
list1_2 = list1_1 # Python 中的赋值语句不复制对象,它们会在目标和对象之间创建绑定关系
list1_3 = list1_1[:] # 通过分配整个列表的切片来制作列表的浅拷贝
list1_4 = list1_1.copy() # 使用 list.copy() 来制作列表的浅拷贝
# 同理,可以使用 dict.copy() 来制作字典的浅拷贝
print("list1_1 =", list1_1)
print("list1_2 =", list1_2)
print("list1_3 =", list1_3)
print("list1_4 =", list1_4)
print(‘-‘*30)
print("id(list1_1) =", id(list1_1))
print("id(list1_2) =", id(list1_2))
print("id(list1_3) =", id(list1_3))
print("id(list1_4) =", id(list1_4))
list1_1 = [1, 2, 3, 4, 5]
list1_2 = [1, 2, 3, 4, 5]
list1_3 = [1, 2, 3, 4, 5]
list1_4 = [1, 2, 3, 4, 5]
------------------------------
id(list1_1) = 1790322044808
id(list1_2) = 1790322044808
id(list1_3) = 1790321996744
id(list1_4) = 1790321982024
# 例2 从对象的元素上看(我可能有些啰嗦了)
list2_1 = [1, 2, 3, 4, 5]
list2_2 = list2_1 # 赋值
list2_3 = list2_1[:] # 浅拷贝
list2_4 = list2_1.copy() # 浅拷贝
print("list2_1 =", list2_1)
print("list2_2 =", list2_2)
print("list2_3 =", list2_3)
print("list2_4 =", list2_4)
print(‘-‘*30)
list2_1[0] = 661
print("* list2_1 =", list2_1)
print("* list2_2 =", list2_2)
print("* list2_3 =", list2_3)
print("* list2_4 =", list2_4)
print(‘-‘*30)
list2_2[1] = 662
print("* list2_1‘ =", list2_1)
print("* list2_2‘ =", list2_2)
print("* list2_3‘ =", list2_3)
print("* list2_4‘ =", list2_4)
print(‘-‘*30)
list2_3[2] = 663
print("* list2_1‘‘ =", list2_1)
print("* list2_2‘‘ =", list2_2)
print("* list2_3‘‘ =", list2_3)
print("* list2_4‘‘ =", list2_4)
print(‘-‘*30)
list2_4[3] = 664
print("* list2_1‘‘‘ =", list2_1)
print("* list2_2‘‘‘ =", list2_2)
print("* list2_3‘‘‘ =", list2_3)
print("* list2_4‘‘‘ =", list2_4)
list2_1 = [1, 2, 3, 4, 5]
list2_2 = [1, 2, 3, 4, 5]
list2_3 = [1, 2, 3, 4, 5]
list2_4 = [1, 2, 3, 4, 5]
------------------------------
* list2_1 = [661, 2, 3, 4, 5]
* list2_2 = [661, 2, 3, 4, 5]
* list2_3 = [1, 2, 3, 4, 5]
* list2_4 = [1, 2, 3, 4, 5]
------------------------------
* list2_1‘ = [661, 662, 3, 4, 5]
* list2_2‘ = [661, 662, 3, 4, 5]
* list2_3‘ = [1, 2, 3, 4, 5]
* list2_4‘ = [1, 2, 3, 4, 5]
------------------------------
* list2_1‘‘ = [661, 662, 3, 4, 5]
* list2_2‘‘ = [661, 662, 3, 4, 5]
* list2_3‘‘ = [1, 2, 663, 4, 5]
* list2_4‘‘ = [1, 2, 3, 4, 5]
------------------------------
* list2_1‘‘‘ = [661, 662, 3, 4, 5]
* list2_2‘‘‘ = [661, 662, 3, 4, 5]
* list2_3‘‘‘ = [1, 2, 663, 4, 5]
* list2_4‘‘‘ = [1, 2, 3, 664, 5]
# 例3 从元素的地址上看
list3_1 = [0, 1, 2, [3, 4, 5]]
list3_2 = list3_1 # 赋值
list3_3 = list3_1[:] # 浅拷贝
list3_4 = list3_1.copy() # 浅拷贝
print("list3_1 =", list3_1)
print("list3_2 =", list3_2)
print("list3_3 =", list3_3)
print("list3_4 =", list3_4)
print(‘-‘*30)
print("id(list3_1[0]) =", id(list3_1[0]))
print("id(list3_2[0]) =", id(list3_2[0]))
print("id(list3_3[0]) =", id(list3_3[0]))
print("id(list3_4[0]) =", id(list3_4[0]))
print(‘-‘*30)
print("id(list3_1[3]) =", id(list3_1[3]))
print("id(list3_2[3]) =", id(list3_2[3]))
print("id(list3_3[3]) =", id(list3_3[3]))
print("id(list3_4[3]) =", id(list3_4[3]))
print(‘-‘*30)
print("id(list3_1[3][0]) =", id(list3_1[3][0]))
print("id(list3_2[3][0]) =", id(list3_2[3][0]))
print("id(list3_3[3][0]) =", id(list3_3[3][0]))
print("id(list3_4[3][0]) =", id(list3_4[3][0]))
list3_1 = [0, 1, 2, [3, 4, 5]]
list3_2 = [0, 1, 2, [3, 4, 5]]
list3_3 = [0, 1, 2, [3, 4, 5]]
list3_4 = [0, 1, 2, [3, 4, 5]]
------------------------------
id(list3_1[0]) = 140720367595232
id(list3_2[0]) = 140720367595232
id(list3_3[0]) = 140720367595232
id(list3_4[0]) = 140720367595232
------------------------------
id(list3_1[3]) = 2859246390984
id(list3_2[3]) = 2859246390984
id(list3_3[3]) = 2859246390984
id(list3_4[3]) = 2859246390984
------------------------------
id(list3_1[3][0]) = 140720367595328
id(list3_2[3][0]) = 140720367595328
id(list3_3[3][0]) = 140720367595328
id(list3_4[3][0]) = 140720367595328
# 例4.1 关于层数(第 2 层)
list4_1 = [0, 1, 2, [3, 4, 5]]
list4_2 = list4_1
list4_3 = list4_1[:]
list4_4 = list4_1.copy()
print("list4_1 =", list4_1)
print("list4_2 =", list4_2)
print("list4_3 =", list4_3)
print("list4_4 =", list4_4)
print(‘-‘*30)
list4_1[3].append(6)
print("* list4_1 =", list4_1)
print("* list4_2 =", list4_2)
print("* list4_3 =", list4_3)
print("* list4_4 =", list4_4)
print(‘-‘*30)
list4_2[3].append(7)
print("* list4_1‘ =", list4_1)
print("* list4_2‘ =", list4_2)
print("* list4_3‘ =", list4_3)
print("* list4_4‘ =", list4_4)
print(‘-‘*30)
list4_3[3][0] = 666
print("* list4_1‘‘ =", list4_1)
print("* list4_2‘‘ =", list4_2)
print("* list4_3‘‘ =", list4_3)
print("* list4_4‘‘ =", list4_4)
print(‘-‘*30)
list4_4[3][1] = 888
print("* list4_1‘‘‘ =", list4_1)
print("* list4_2‘‘‘ =", list4_2)
print("* list4_3‘‘‘ =", list4_3)
print("* list4_4‘‘‘ =", list4_4)
list4_1 = [0, 1, 2, [3, 4, 5]]
list4_2 = [0, 1, 2, [3, 4, 5]]
list4_3 = [0, 1, 2, [3, 4, 5]]
list4_4 = [0, 1, 2, [3, 4, 5]]
------------------------------
* list4_1 = [0, 1, 2, [3, 4, 5, 6]]
* list4_2 = [0, 1, 2, [3, 4, 5, 6]]
* list4_3 = [0, 1, 2, [3, 4, 5, 6]]
* list4_4 = [0, 1, 2, [3, 4, 5, 6]]
------------------------------
* list4_1‘ = [0, 1, 2, [3, 4, 5, 6, 7]]
* list4_2‘ = [0, 1, 2, [3, 4, 5, 6, 7]]
* list4_3‘ = [0, 1, 2, [3, 4, 5, 6, 7]]
* list4_4‘ = [0, 1, 2, [3, 4, 5, 6, 7]]
------------------------------
* list4_1‘‘ = [0, 1, 2, [666, 4, 5, 6, 7]]
* list4_2‘‘ = [0, 1, 2, [666, 4, 5, 6, 7]]
* list4_3‘‘ = [0, 1, 2, [666, 4, 5, 6, 7]]
* list4_4‘‘ = [0, 1, 2, [666, 4, 5, 6, 7]]
------------------------------
* list4_1‘‘‘ = [0, 1, 2, [666, 888, 5, 6, 7]]
* list4_2‘‘‘ = [0, 1, 2, [666, 888, 5, 6, 7]]
* list4_3‘‘‘ = [0, 1, 2, [666, 888, 5, 6, 7]]
* list4_4‘‘‘ = [0, 1, 2, [666, 888, 5, 6, 7]]
从例3 的 id 也不难想象这个结果。
# 例4.2 关于层数(第 1 层;我啰嗦了,此例同例2)
list4_1 = [0, 1, 2, [3, 4, 5]]
list4_2 = list4_1
list4_3 = list4_1[:]
list4_4 = list4_1.copy()
print("list4_1 =", list4_1)
print("list4_2 =", list4_2)
print("list4_3 =", list4_3)
print("list4_4 =", list4_4)
print(‘-‘*50)
list4_1.append(6)
print("* list4_1 =", list4_1)
print("* list4_2 =", list4_2)
print("* list4_3 =", list4_3)
print("* list4_4 =", list4_4)
print(‘-‘*50)
list4_2.extend([7, 8])
print("* list4_1‘ =", list4_1)
print("* list4_2‘ =", list4_2)
print("* list4_3‘ =", list4_3)
print("* list4_4‘ =", list4_4)
print(‘-‘*50)
list4_3.insert(3, "YorkFish")
print("* list4_1‘‘ =", list4_1)
print("* list4_2‘‘ =", list4_2)
print("* list4_3‘‘ =", list4_3)
print("* list4_4‘‘ =", list4_4)
print(‘-‘*50)
list4_4.insert(0, "YorkFish")
print("* list4_1‘‘‘ =", list4_1)
print("* list4_2‘‘‘ =", list4_2)
print("* list4_3‘‘‘ =", list4_3)
print("* list4_4‘‘‘ =", list4_4)
list4_1 = [0, 1, 2, [3, 4, 5]]
list4_2 = [0, 1, 2, [3, 4, 5]]
list4_3 = [0, 1, 2, [3, 4, 5]]
list4_4 = [0, 1, 2, [3, 4, 5]]
--------------------------------------------------
* list4_1 = [0, 1, 2, [3, 4, 5], 6]
* list4_2 = [0, 1, 2, [3, 4, 5], 6]
* list4_3 = [0, 1, 2, [3, 4, 5]]
* list4_4 = [0, 1, 2, [3, 4, 5]]
--------------------------------------------------
* list4_1‘ = [0, 1, 2, [3, 4, 5], 6, 7, 8]
* list4_2‘ = [0, 1, 2, [3, 4, 5], 6, 7, 8]
* list4_3‘ = [0, 1, 2, [3, 4, 5]]
* list4_4‘ = [0, 1, 2, [3, 4, 5]]
--------------------------------------------------
* list4_1‘‘ = [0, 1, 2, [3, 4, 5], 6, 7, 8]
* list4_2‘‘ = [0, 1, 2, [3, 4, 5], 6, 7, 8]
* list4_3‘‘ = [0, 1, 2, ‘YorkFish‘, [3, 4, 5]]
* list4_4‘‘ = [0, 1, 2, [3, 4, 5]]
--------------------------------------------------
* list4_1‘‘‘ = [0, 1, 2, [3, 4, 5], 6, 7, 8]
* list4_2‘‘‘ = [0, 1, 2, [3, 4, 5], 6, 7, 8]
* list4_3‘‘‘ = [0, 1, 2, ‘YorkFish‘, [3, 4, 5]]
* list4_4‘‘‘ = [‘YorkFish‘, 0, 1, 2, [3, 4, 5]]
# 例5 赋值与浅拷贝、深拷贝的不同
import copy # 导入 copy 模块
list5_1 = [0, 1, 2, [‘a‘, ‘b‘]]
list5_2 = list5_1 # 赋值
list5_3 = list5_1.copy() # 浅拷贝;用 list5_1[:] 效果一样
list5_4 = copy.copy(list5_1) # 浅拷贝
list5_5 = copy.deepcopy(list5_1) # 迟来的深拷贝
print("list5_1 =", list5_1)
print("list5_2 =", list5_2)
print("list5_3 =", list5_3)
print("list5_4 =", list5_4)
print("list5_5 =", list5_5)
print(‘-‘*30)
list5_1.append(4)
list5_1[3].append(‘c‘)
print("list5_1‘ =", list5_1)
print("list5_2‘ =", list5_2)
print("list5_3‘ =", list5_3)
print("list5_4‘ =", list5_4)
print("list5_5‘ =", list5_5)
list5_1 = [0, 1, 2, [‘a‘, ‘b‘]]
list5_2 = [0, 1, 2, [‘a‘, ‘b‘]]
list5_3 = [0, 1, 2, [‘a‘, ‘b‘]]
list5_4 = [0, 1, 2, [‘a‘, ‘b‘]]
list5_5 = [0, 1, 2, [‘a‘, ‘b‘]]
------------------------------
list5_1‘ = [0, 1, 2, [‘a‘, ‘b‘, ‘c‘], 4]
list5_2‘ = [0, 1, 2, [‘a‘, ‘b‘, ‘c‘], 4]
list5_3‘ = [0, 1, 2, [‘a‘, ‘b‘, ‘c‘]]
list5_4‘ = [0, 1, 2, [‘a‘, ‘b‘, ‘c‘]]
list5_5‘ = [0, 1, 2, [‘a‘, ‘b‘]]
深拷贝的第二层没有像浅拷贝一样随原对象的变化而变化。
# 例6 “不动如山”的不可变元素
import copy
list6_1 = [0, 1, 2, (3, 4, 5)]
list6_2 = list6_1
list6_3 = list6_1.copy() # 用 list6_1[:] 效果一样
list6_4 = copy.copy(list6_1)
list6_5 = copy.deepcopy(list6_1)
print("list6_1 =", list6_1)
print("list6_2 =", list6_2)
print("list6_3 =", list6_3)
print("list6_4 =", list6_4)
print("list6_5 =", list6_5)
print(‘-‘*30)
print("id(ist6_1[3]) =", id(list6_1[3]))
print("id(ist6_2[3]) =", id(list6_2[3]))
print("id(ist6_3[3]) =", id(list6_3[3]))
print("id(ist6_4[3]) =", id(list6_4[3]))
print("id(ist6_5[3]) =", id(list6_5[3]))
print(‘-‘*30)
list6_1[3] = (6, 6, 6) # list6_1 与 list6_2 是一体的
print("list6_1‘ =", list6_1)
print("list6_2‘ =", list6_2)
print("list6_3‘ =", list6_3)
print("list6_4‘ =", list6_4)
print("list6_5‘ =", list6_5)
print(‘-‘*30)
print("id(ist6_1[3]‘) =", id(list6_1[3]))
print("id(ist6_2[3]‘) =", id(list6_2[3]))
print("id(ist6_3[3]‘) =", id(list6_3[3]))
print("id(ist6_4[3]‘) =", id(list6_4[3]))
print("id(ist6_5[3]‘) =", id(list6_5[3]))
print(‘-‘*30)
list6_2[3] = (8, 8, 8)
list6_3[3] = (8, 8, 8)
list6_4[3] = (8, 8, 8)
list6_5[3] = (8, 8, 8)
print("list6_1‘‘ =", list6_1)
print("list6_2‘‘ =", list6_2)
print("list6_3‘‘ =", list6_3)
print("list6_4‘‘ =", list6_4)
print("list6_5‘‘ =", list6_5)
print(‘-‘*30)
print("id(ist6_1[3]‘‘) =", id(list6_1[3]))
print("id(ist6_2[3]‘‘) =", id(list6_2[3]))
print("id(ist6_3[3]‘‘) =", id(list6_3[3])) # 注意 id
print("id(ist6_4[3]‘‘) =", id(list6_4[3])) # 注意 id
print("id(ist6_5[3]‘‘) =", id(list6_5[3])) # 注意 id
list6_1 = [0, 1, 2, (3, 4, 5)]
list6_2 = [0, 1, 2, (3, 4, 5)]
list6_3 = [0, 1, 2, (3, 4, 5)]
list6_4 = [0, 1, 2, (3, 4, 5)]
list6_5 = [0, 1, 2, (3, 4, 5)]
------------------------------
id(ist6_1[3]) = 2683399214208
id(ist6_2[3]) = 2683399214208
id(ist6_3[3]) = 2683399214208
id(ist6_4[3]) = 2683399214208
------------------------------
list6_1‘ = [0, 1, 2, (6, 6, 6)]
list6_2‘ = [0, 1, 2, (6, 6, 6)]
list6_3‘ = [0, 1, 2, (3, 4, 5)]
list6_4‘ = [0, 1, 2, (3, 4, 5)]
list6_5‘ = [0, 1, 2, (3, 4, 5)]
------------------------------
id(ist6_1[3]‘) = 2683399759624
id(ist6_2[3]‘) = 2683399759624
id(ist6_3[3]‘) = 2683399214208
id(ist6_4[3]‘) = 2683399214208
id(ist6_5[3]‘) = 2683399214208
------------------------------
list6_1‘‘ = [0, 1, 2, (8, 8, 8)]
list6_2‘‘ = [0, 1, 2, (8, 8, 8)]
list6_3‘‘ = [0, 1, 2, (8, 8, 8)]
list6_4‘‘ = [0, 1, 2, (8, 8, 8)]
list6_5‘‘ = [0, 1, 2, (8, 8, 8)]
------------------------------
id(ist6_1[3]‘‘) = 2683399916856
id(ist6_2[3]‘‘) = 2683399916856
id(ist6_3[3]‘‘) = 2683399968520
id(ist6_4[3]‘‘) = 2683399759624
id(ist6_5[3]‘‘) = 2683399921880
Python3 能“偷懒”时必“偷懒”,对于可变元素,有变化才分配新地址。
在下学识有限,不足之处,还请诸位多多指教!
标签:通过 赋值 不可变 递归循环 例子 没有 port 情况下 tab
原文地址:https://www.cnblogs.com/yorkyu/p/10326739.html