深淺拷貝:數(shù)據(jù)分離情況
1. =賦值:數(shù)據(jù)完全共享(指向內(nèi)存中的同一個對象)
被賦值的變量指向的數(shù)據(jù)和原變量的數(shù)據(jù)都是指向內(nèi)存中的同一個地址:
(1)如果是不可變數(shù)據(jù)類型(數(shù)字、字符串等),修改其中的一個值,實際是修改了變量指向與值對應的地址(相當于重新被賦值),因此會同時發(fā)生變化;
(2)如果是可變數(shù)據(jù)類型(列表、字典等),在修改數(shù)據(jù)時僅僅是其本身的地址指向發(fā)生了改變,但是指向可變數(shù)據(jù)類型的地址并未改變,因此會同時發(fā)生改變。
print("以下是賦值")
a=[1,2,"4",[4,5]]
b=a
print(a)
print(b)
b[0]=11
b[3][0]=44
print(a)
print(b)
結(jié)果:
以下是賦值
[1, 2, '4', [4, 5]]
[1, 2, '4', [4, 5]]
[11, 2, '4', [44, 5]]
[11, 2, '4', [44, 5]]
2. 淺copy:數(shù)據(jù)半共享(僅可變數(shù)據(jù)類型指向同一個對象)
復制其數(shù)據(jù)獨立內(nèi)存存放(新建一個地址指向),但是只拷貝成功第一層:
(1)如果是不可變數(shù)據(jù)類型(數(shù)字、字符串等),修改其中一個變量的值,由于淺copy的兩個變量的地址指向獨立,因此只有本身值被修改的變量發(fā)生變化,另一個不會改變;
(2)如果是可變數(shù)據(jù)類型(列表、字典等),在修改數(shù)據(jù)時僅僅是其本身的地址指向發(fā)生了改變,但是指向可變數(shù)據(jù)類型的地址并未改變,因此會同時發(fā)生改變。
print("以下是淺拷貝")
a=[1,2,"4",[4,5]]
b=a.copy()
print(a)
print(b)
b[0]=11
b[3][0]=44
print(a)
print(b)
結(jié)果:
以下是淺拷貝
[1, 2, '4', [4, 5]]
[1, 2, '4', [4, 5]]
[1, 2, '4', [44, 5]]
[11, 2, '4', [44, 5]]
3. 深copy:數(shù)據(jù)完全不共享(數(shù)據(jù)獨立,互不影響)
復制其數(shù)據(jù)完完全全放獨立的一個內(nèi)存,完全拷貝,數(shù)據(jù)不共享:
(1)如果是不可變數(shù)據(jù)類型(數(shù)字、字符串等),修改其中一個變量的值,由于深copy的兩個變量的地址指向獨立,因此只有本身值被修改的變量發(fā)生變化,另一個不會改變;
(2)如果是可變數(shù)據(jù)類型(列表、字典等),在修改數(shù)據(jù)時僅僅是其本身的地址指向發(fā)生了改變,由于是深copy,指向可變數(shù)據(jù)類型的地址完全獨立,因此另一個變量不會發(fā)生改變。
print("以下是深拷貝")
import copy
a=[1,2,"4",[4,5]]
b=copy.deepcopy(a)
print(a)
print(b)
b[0]=11
b[3][0]=44
print(a)
print(b)
結(jié)果:
以下是深拷貝
[1, 2, '4', [4, 5]]
[1, 2, '4', [4, 5]]
[1, 2, '4', [4, 5]]
[11, 2, '4', [44, 5]]