python之賦值,深拷貝,淺拷貝的區別

2021-10-01 18:39:58 字數 2956 閱讀 7236

賦值:

賦值其實就是簡單的純物件引用,並不會產生拷貝內容的操作

a =[1

,2,3

]b = a

print(id

(a),

id(b)

)# 1998317600136 1998317600136

print

(a is b)

# true

可以發現a, b是指向同乙個位址的.因此除了 b這個名字之外,賦值操作並沒有其他記憶體開銷.

因此,修改a,b中任何乙個都會修改對方的值.

淺拷貝:

淺拷貝會建立乙個新物件,並且只拷貝原物件,但是子物件是對原物件內子物件的引用.

淺拷貝有三種形式:

import copy

a =[1,

2,3,

[2,3

]]b = a[:]

# 切片操作

b =list()

# 工廠函式

b = copy.copy(a)

# copy函式

print

(a is b)

# false

for i in

range(0

,4):

print

(a[i]

is b[i]

)# true true true true

可以發現,a,b是不同的物件;

但是a,b中的相對應的子物件(指的是a,b列表中的元素)的位址是相同的;

因此淺拷貝之所以叫做淺拷貝,是因為只拷貝了原物件第一層,而其它層是對原物件的引用;

深拷貝深拷貝相對淺拷貝而言,深拷貝拷貝的層級更深,包含所有層級,因此它的時間成本很高.

import copy

a =[1,

2,3,

[2,3

]]c = copy.deepcopy(a)

# 深拷貝唯一形式,copy函式

print

(c is a)

# flase

深拷貝跟淺拷貝一樣,會建立新的物件,且與原物件沒有任何關聯,並不會相互影響.

import copy

a =[1,

2,3,

[2,3

]]b = a

c = copy.copy(a)

# copy函式

d = copy.deepcopy(a)5)

#操作1a[3

]'hello'

)#操作2

print(id

(a),

id(b),id

(c),

id(d)

)#1437646497288 1437646497288 1437646514632 1437646514440

print

(a, b, c, d)

# [1, 2, 3, [2, 3, 'hello'], 5]

# [1, 2, 3, [2, 3, 'hello'], 5]

# [1, 2, 3, [2, 3, 'hello']]

# [1, 2, 3, [2, 3]]

解析:

id解析

b是賦值產生的,因此與a是同乙個物件,而深拷貝和淺拷貝都會產生新的物件;

值解析b 與 a 是同乙個物件,因此a 改變,b也會跟隨改變,始終保持一致;

c 是淺拷貝產生的只拷貝了本物件第一層,因此第一層不會改變,而子物件是引用a的,因此子物件會跟隨a改變;

d 是深拷貝產生的,複製了原a的所有層級,不包含任何引用,與a沒有任何關聯,即使a的任何層級改變,d也不會發生任何改變.

參考以下**

import copy

a =[1,

2,3,

[4,[

5,6]

]]b = copy.deepcopy(a)

print

((a[0]

)is(b[0])

)# true 不可變元素位址相同

print

((a[1]

)is(b[1])

)# true 不可變元素位址相同

print

((a[2]

)is(b[2])

)# true 不可變元素位址相同

print

((a[3]

)is(b[3])

)# false 可變元素位址相同

print

((a[3]

[0])

is(b[3]

[0])

)# true 不可變元素位址相同

print

((a[3]

[1])

is(b[3]

[1])

)# false 可變元素位址相同

print

((a[3]

[1][

0])is

(b[3][

1][0

]))# true 不可變元素位址相同

print

((a[3]

[1][

1])is

(b[3][

1][1

]))# true 不可變元素位址相同

看到這是不是覺得有所疑惑?甚至顛覆認知?為什麼深拷貝後產生的物件中的部分子物件與原物件中對應的子物件是相同的位址呢?(不是應該所有子物件都不同位址嗎?)

這就要說到python記憶體管理中的物件儲存機制(此處不細說)。

python對於整數(-5~256)和短字串是快取在記憶體當中的,這些物件在記憶體中只有乙個,無論如何拷貝都不會產生複製物件,這是python節省記憶體空間的機制。

換句話說,在python中對於數字,(短)字元等原子型別是沒有拷貝一說的,即使是深拷貝,產生的也是對原物件的引用.如果元組中含有原子型別,即使是深拷貝,得到的也是淺拷貝。

Python 賦值 淺拷貝 深拷貝

賦值 a b,只拷貝了物件的引用,沒有拷貝內容。兩個物件的id一樣 淺拷貝 copy.copy 構造乙個新的復合物件,然後將子物件引用插入到原始物件的副本中。深拷貝 copy.deepcopy 構造乙個新的復合物件,然後遞迴地將子物件副本插入原始物件的副本。給個栗子 從這個栗子可以看出,對c進行修改...

python賦值 淺拷貝 深拷貝

視覺化 首先了解知識點 可變 list,dict 和不可變 string,int,tuple 淺拷貝 對於string int來說沒有意義,因為它們資料就一層,對於tuple由於是不可變型別所以新的物件會指向原來的物件位址,對於list和dict,新的物件會在記憶體中開闢乙個新的記憶體空間,並且只拷...

淺拷貝 深拷貝和淺賦值 深賦值

include includeusing namespace std class string else 淺拷貝 也就是系統預設的拷貝,可寫可不寫。string const string s 預設的拷貝構造 深拷貝 string const string s string s2 s1 深賦值 str...