在理解淺拷貝和深拷貝之前,首先要理解學習一下變量在Python中是怎樣存儲的;
變量的類型是分值引用與地址引用兩種.
python的一切變量都是對象,變量的存儲,采用了地址引用的方式,存儲的只是一個變量的值所在的內存地址,而不是這個變量的只本身。
在Python中,是有多種數據類型:bool、int、long、float、string、list、dict、tuple、set;
其中可分為基本數據類型和復雜數據結構;
基本數據類型:bool、int、long、float、string;
復雜數據結構:list、dict、tuple、set;(對於能存儲基本數據類型的變量可以把它看做復雜數據結構)
由於Python中的變量存儲都是地址引用,所以說復雜數據結構(list、dict、tuple、set)中存儲的變量也僅僅是變量的地址。
一、變量的初始化(賦值):
1.Python中變量的初始化就是在內存中新開辟一塊存儲變量的值的內存,把這塊內存的地址賦值給變量。(變量中存的是值的地址)
1 >>> str_1 = 'abc' 2 >>> id(str_1) 3 4300773168 4 >>> str_2 = str_1 5 >>> id(str_2) 6 4300773168
在給已經初始化的變量重新初始化的時候,就會重新更改變量中的地址。
1 >>> str_1 = 123 2 >>> id(str_2) 3 4300773168 4 >>> id(str_1) 5 4297541792
2.而在復雜數據結構中,更改數據結構中的元素(基本數據類型),僅僅是改變了這個元素的地址,而不會影響復雜數據結構本身的地址。
1 >>> list_1 =[1,2,3] 2 >>> id(list_1) 3 4320183368 4 >>> list_1.append(9) 5 >>> list_1[2] = 22 6 >>> list_1.pop(2) 7 3 8 >>> print(list_1,id(list_1)) 9 [1, 2, 22, 5, 6, 9] 4320183368
通過上邊的事例做出結論:
當復雜數據結構(list、dict、tuple、set)賦值時,是在計算機中開辟一塊內存來存儲這個復雜數據結構的值,而修改其中元素的時候只是更改了復雜數據結構的元素的地址,不會影響復雜數據結構的地址(就像一個桌子上有坐着兩個人,而桌子上的菜兩個人是共同享有);當重新賦值時,會重新開辟新的內存來存儲變量的值,把這塊內存的地址存到變量中。(相當於桌子上的一個人移到了另一個桌子上吃)
二、拷貝:
在Python中,我們有時候要保存一份數據,再去對這塊數據進行處理,而這個時候Python提供了兩種拷貝方式:淺拷貝、深拷貝。
1.淺拷貝
淺拷貝: 不管是多么復雜的數據結構,淺拷貝只會拷貝第一層.
1 import copy 2 list_1 = [1,2,['a','b','c'],3] 3 list_2 = list_1[:] 4 # list_2 = copy.copy(list_1)淺拷貝的另一種方式 5 list_1[2][1] = 'kk' 6 print(list_1,list_2,id(list_1[2]),id(list_2[2])) 7 [1, 2, ['a', 'kk', 'c'], 3] [1, 2, ['a', 'kk', 'c'], 3] 4330513736 4330513736
由於淺拷貝只會拷貝list_1的第一層,所以元素中的list的地址沒有被更改,說明list_1和list_2共享同一個第二層的list。
2.深拷貝:
深拷貝會完全復制原變量的所有數據,在內存中生成一套完全一樣的內容,我們對這兩個變量中的一個進行任意修改都不會影響另一個變量。
1 import copy 2 list_1 = [1,2,['a','b','c'],3] 3 list_2 = copy.deepcopy(list_1) 4 list_1[2][1] = 'kk' 5 print(list_1,list_2,list_1[2],list_2[2]) 6 [1, 2, ['a', 'kk', 'c'], 3] [1, 2, ['a', 'b', 'c'], 3] 4330513736 4330512584