1. 程式人生 > >python的賦值、深拷貝和淺拷貝三者之間的區別

python的賦值、深拷貝和淺拷貝三者之間的區別

python的賦值、淺拷貝和深拷貝三者之間的區別

類似的文章已經很多了,但是在學習過程中,還是有一些模糊的地方,所以這裡把自己的理解記錄下來,便於以後複習,溫故知新!

1.賦值

  • 賦值是將一個物件的地址賦值給一個變數,讓變數指向該地址( 舊瓶裝舊酒 )。
  • 修改不可變物件(str、tuple)需要開闢新的空間
  • 修改可變物件(list等)不需要開闢新的空間

2.淺拷貝和深拷貝

淺拷貝

是在另一塊地址中建立一個新的變數或容器,但是容器內的元素的地址均是源物件的元素的地址的拷貝。也就是說新的容器中指向了舊的元素( 新瓶裝舊酒 )。


深拷貝

是在另一塊地址中建立一個新的變數或容器,同時容器內的元素的地址也是新開闢的,僅僅是值相同而已,是完全的副本。也就是說( 新瓶裝新酒 )。


具體例子:

import copy
a = [1, 2, 3, 4, ['a', 'b']]  #原始物件
print ('a = ', a,'\n', 'id(a):',id(a))

print('-----------原始物件各元素地址----------')
for i in a:
    print('%s:'%i,'id:(%s)'%id(i))

b = a  #賦值,傳物件的引用
c = copy.copy(a)  #物件拷貝,淺拷貝
print('-----------淺拷貝後各元素地址----------') for m in c: print('%s:'%m,'id:%s'%id(m)) print('-----------深拷貝後各元素地址----------') d = copy.deepcopy(a) #物件拷貝,深拷貝 for n in d: print('%s:'%n,'id:%s'%id(n)) a.append(5) #修改物件a a[4].append('c') #修改物件a中的['a', 'b']陣列物件 print('-----------原始變數改變後,淺拷貝物件的各元素地址----------'
) for m in c: print('%s:'%m,'id:%s'%id(m)) print('-----------原始變數改變後,深拷貝物件的各元素地址----------') for n in d: print('%s:'%n,'id:%s:'%id(n)) print ('a = ', a,'\n', 'id(a):',id(a)) print ('b = ', b,'\n','id(b):',id(b)) print ('c = ', c,'\n','id(c):',id(c)) print ('d = ', d,'\n','id(d):',id(d))

列印結果:

# 最初的a,
 a =  [1, 2, 3, 4, ['a', 'b']] 
 id(a): 2215279651016
#  每一個元素的地址,可以發現,對於不可變數(str,tuple,num)的地址是不變的;但是對於可變變數(list,dict)淺拷貝是不變的,但是深拷貝就賦予該型別變數一個新的地址。
-----------原始物件各元素地址----------
1: id:1710535744
2: id:1710535776
3: id:1710535808
4: id:1710535840
['a', 'b']: id:2215531253256
-----------淺拷貝後各元素地址----------
1: id:1710535744
2: id:1710535776
3: id:1710535808
4: id:1710535840
['a', 'b']: id:2215531253256
-----------深拷貝後各元素地址----------
1: id:1710535744
2: id:1710535776
3: id:1710535808
4: id:1710535840
['a', 'b']: id:2215279696456
-----------原始變數改變後,淺拷貝物件的各元素地址----------
1: id:1710535744
2: id:1710535776
3: id:1710535808
4: id:1710535840
['a', 'b', 'c']: id:2215531253256

 # 淺拷貝只是拷貝了當時a的地址,所以當對a添加了‘5’時,其實a的地址已經變化了
-----------原始變數改變後,深拷貝物件的各元素地址----------
1: id:1710535744
2: id:1710535776
3: id:1710535808
4: id:1710535840
['a', 'b']: id:2215279696456

 # 此時的a本身
a =  [1, 2, 3, 4, ['a', 'b', 'c'], 5] 
 id(a): 2215279651016 id(a[5]): 1710535872

  # b地址指向a
b =  [1, 2, 3, 4, ['a', 'b', 'c'], 5] 
 id(b): 2215279651016
 # c 淺拷貝的變數地址發生變化,不包含a中的元素5.說明淺拷貝只是拷貝了a變數的元素地址,當a中增加或減少元素時,該變數的地址也會發生變化。
c =  [1, 2, 3, 4, ['a', 'b', 'c']] 
 id(c): 2215279695112

d =  [1, 2, 3, 4, ['a', 'b']] 
 id(d): 2215279650120