Python 引用 淺拷貝 深拷貝解析

2021-09-10 17:17:49 字數 2622 閱讀 1501

1、=的作用。

僅僅是位址的引用,當原列表或者新列表中任意元素改變,均會對另外乙個產生影響

# 引用

# 本例中屬於位址的引用,其中a和b共用同一塊記憶體

# 當修改共用記憶體中的任意的內容是時,均會影響到另外的內容

a = [0, 1, 2, [3, 4]]

b = a

# 修改a[0]後,a[0]和b[0]都會改變

a[0] = 10

print("a:", a)

print("b:", b)

# 修改b[0]後,a[0]和b[0]都會改變

b[0] = 0

print("a:", a)

print("b:", b)

# 修改a[3][0]後,a[3][0]和b[3][0]都會改變

a[3][0] = 30

print("a:", a)

print("b:", b)

# 修改b[3][0]後,a[3][0]和b[3][0]都會改變

b[3][0] = 3

print("a:", a)

print("b:", b)

# 可以看到兩個列表的記憶體位址相同

2、使用列表的copy()方法或者copy模組的copy()方法實現拷貝

a = ["a0", "a1", "a2", ["a3", "a4"]]

b = a.copy()

# print("a:", a)

# print("b:", b)

通過列表的copy()方法,可以得到乙個與原列表相同的列表,當通過id()方法,檢視兩者的記憶體位址時,可以發現,兩者的記憶體位址不同,可以當做將原列表拷貝了乙份,而不是對於位址的引用。

但是,當對a列表或者b列表的前三個元素進行修改時,可以觀察到僅修改了乙個列表內的元素,對於另外乙個列表的元素沒有影響。比如

a[0] = 0

b[1] = 1

print(a) #[0, 'a1', 'a2', ['a3', 'a4']]

print(b) #['a0', 1, 'a2', ['a3', 'a4']]

可以看出,修改a[0]或者b[1]時均不會修改另乙個列表的對應元素。然而有例外,看下面的例子

print(a)  # ['a0', 'a1', 'a2', ['a3', 'a4']]

print(b) # ['a0', 'a1', 'a2', ['a3', 'a4']]

a[3][0] = 3

print(a) # ['a0', 'a1', 'a2', [3, 'a4']]

print(b) # ['a0', 'a1', 'a2', [3, 'a4']]

b[3][1] = 4

print(a) # ['a0', 'a1', 'a2', [3, 4]]

print(b) # ['a0', 'a1', 'a2', [3, 4]]

當修改a[3][0]時,b[3][0]也會跟著改變,當使用id()函式檢視a[3][0]和b[3][0]時發現兩者的記憶體位址相同,可以認為b[3][0]並不是從a那裡複製了乙份,而是直接指向了a[3][0]的記憶體位址,這樣就可以解釋為什麼修改a列表的的列表時會影響到其他的了。

3、將所有的資料拷貝乙份,需要使用copy模組的 deepcopy()方法

import copy

a = ["a0", "a1", "a2", ["a3", "a4"]]

b = copy.deepcopy(a)

使用deepcopy()方法實現列表的深拷貝,這種方式將原列表的元素拷貝乙份,無論原列表內是否存在巢狀。

print(a)  # ['a0', 'a1', 'a2', ['a3', 'a4']]

print(b) # ['a0', 'a1', 'a2', ['a3', 'a4']]

a[3][0] = 3

print(a) # ['a0', 'a1', 'a2', [3, 'a4']]

print(b) # ['a0', 'a1', 'a2', ['a3', 'a4']]

b[3][1] = 4

print(a) # ['a0', 'a1', 'a2', [3, 'a4']]

print(b) # ['a0', 'a1', 'a2', ['a3', 4]]

修改內容時僅會改變自身,不會影響其他。

總結:利用=的時候,僅僅是引用,而非拷貝,修改舊的或者新的都會影響另外乙個,牽一髮而動全身。

使用列表的copy方法或者使用copy模組的copy()方法,僅僅開闢一塊新的記憶體空間,將原列表的第一層元素複製乙份新的,而列表內的巢狀不會複製,僅僅是引用了內層列表的位址,屬於空有其表(因為內層的無論通過新列表還是舊列表都能修改)

使用deepcoopy()方法拷貝列表,不僅開闢新空間,而且還將原列表的所有的元素都複製乙份,無論原列表內是否存在巢狀的列表,屬於形神具備(因為內層的列表元素不再是通過引用,而是真真正正的複製了乙份新的)

python 引用,淺拷貝,深拷貝

引用 當物件是不可變型別的時候,int float double string tuple 純tuple 遇到 引用 問題時,雖然起初兩個變數指向同乙個記憶體位址,但是改變了其中乙個值,並不會影響另外乙個 會重新開闢記憶體位址 當物件是可變型別的時候,list dic,遇到 引用 問題,會一直共享一...

Python深拷貝 淺拷貝 引用

列表巢狀 如果想拷貝之後賦值的變數不想影響之前的列 表變數import copy 反之copy usr bin env python coding utf 8 author mxl time 2020 3 17 import copy a 1,2,3 b a a print a的初始值為 str a...

Python引用 淺拷貝 深拷貝

1 概念 深拷貝 將父和子的值都進行傳遞,無論怎麼去修改源變數,深拷貝的變數都和源變數無關 2 引用 我們建立乙個變數a,通過引用將a賦值給變數b,使用id 檢視變數位址,a與b得位址一致,可見兩者此時指向同意記憶體位址,當我們改變a得值時,b得值也會變化。引用示例 a 1 b a print id...