拷貝對(duì)象的意義在于:如果需要在不更改源數(shù)據(jù)的情況下,修改數(shù)據(jù)缸沃,此時(shí)需要一個(gè)拷貝對(duì)象
python提供copy來(lái)完成這樣的拷貝
1恰起、賦值
lst = [1, ['a', 'b']]
L = lst
lst.insert(1, 2)
lst[2].append('c')
print('lst:', lst, 'id:', id(lst))
print('L:', L, 'id:', id(L))
print('lst中元素的value和id')
for i in lst:
print('value:', i, 'id:', id(i))
print('L中元素的value和id')
for i in L:
print('value:', i, 'id:', id(i))
結(jié)果為:
lst: [1, 2, ['a', 'b', 'c']] id: 38425416
L: [1, 2, ['a', 'b', 'c']] id: 38425416
lst中元素的value和id
value: 1 id: 1588096032
value: 2 id: 1588096064
value: ['a', 'b', 'c'] id: 38425224
L中元素的value和id
value: 1 id: 1588096032
value: 2 id: 1588096064
value: ['a', 'b', 'c'] id: 38425224
從上面的結(jié)果得知,賦值并沒(méi)有為 L 建立新的內(nèi)存空間趾牧,lst 的 value 和 id 以及其元素的 value 和 id 都是與 L 相同的检盼,說(shuō)明只是將 L 指向 lst,新的對(duì)象沒(méi)有被創(chuàng)建翘单,你可以理解為一個(gè)人有2個(gè)名字吨枉,雖然不同,但都是同一個(gè)人
2哄芜、淺拷貝
import copy
lst = [1, ['a', 'b']]
L = copy.copy(lst)
print('數(shù)據(jù)操作前l(fā)st和L的id值')
print('id(lst):', id(lst), 'id(L):', id(L))
lst.insert(1, 2)
lst[2].append('c')
print('操作后:')
print('lst:', lst, 'id:', id(lst))
print('L:', L, 'id:', id(L))
print('lst中元素的value和id')
for i in lst:
print('value:', i, 'id:', id(i))
print('L中元素的value和id')
for i in L:
print('value:', i, 'id:', id(i))
結(jié)果:
數(shù)據(jù)操作前l(fā)st和L的id值
id(lst): 38028168 id(L): 38029448
操作后:
lst: [1, 2, ['a', 'b', 'c']] id: 38028168
L: [1, ['a', 'b', 'c']] id: 38029448
lst中元素的value和id
value: 1 id: 1589996576
value: 2 id: 1589996608
value: ['a', 'b', 'c'] id: 38027976
L中元素的value和id
value: 1 id: 1589996576
value: ['a', 'b', 'c'] id: 38027976
從結(jié)果得知貌亭,L 的 id 與 lst 的 id 在數(shù)據(jù)操作前就已經(jīng)不同了,說(shuō)明淺拷貝為拷貝對(duì)象 new 了一個(gè)新對(duì)象认臊,繼續(xù)觀察可以發(fā)現(xiàn)不同的結(jié)果有圃庭,lst新增數(shù)據(jù) 2,而 L并沒(méi)有相應(yīng)增加(因?yàn)樗鼈儗儆趦蓚€(gè)不同的對(duì)象了)
3美尸、深拷貝
import copy
lst = [1, ['a', 'b']]
L = copy.deepcopy(lst)
print('數(shù)據(jù)操作前l(fā)st和L的id值')
print('id(lst):', id(lst), 'id(L):', id(L))
lst.insert(1, 2)
lst[2].append('c')
print('操作后:')
print('lst:', lst, 'id:', id(lst))
print('L:', L, 'id:', id(L))
print('lst中元素的value和id')
for i in lst:
print('value:', i, 'id:', id(i))
print('L中元素的value和id')
for i in L:
print('value:', i, 'id:', id(i))
結(jié)果:
數(shù)據(jù)操作前l(fā)st和L的id值
id(lst): 34096008 id(L): 34097288
操作后:
lst: [1, 2, ['a', 'b', 'c']] id: 34096008
L: [1, ['a', 'b']] id: 34097288
lst中元素的value和id
value: 1 id: 1588096032
value: 2 id: 1588096064
value: ['a', 'b', 'c'] id: 34095816
L中元素的value和id
value: 1 id: 1588096032
value: ['a', 'b'] id: 34097224
我們對(duì)比淺拷貝來(lái)看冤议,深拷貝也是新建了一個(gè)內(nèi)存地址斟薇,不可變對(duì)象 1 還是 1师坎,但可變對(duì)象['a', 'b']也為它新增了一個(gè)內(nèi)存地址,淺拷貝中是沒(méi)有的堪滨,所以淺拷貝中胯陋,list數(shù)據(jù)的改變是同步的,而深拷貝是不一樣的結(jié)果袱箱。
結(jié)論:
- 直接賦值并沒(méi)有新建對(duì)象遏乔,只是多了一個(gè)引用名
- 深、淺拷貝都是對(duì)源對(duì)象的復(fù)制发笔,占用不同的內(nèi)存空間盟萨。區(qū)別在于淺拷貝對(duì)可變對(duì)象的是完全復(fù)制,深拷貝是新建內(nèi)存空間了讨,只復(fù)制其值