Pin-Jiun / Python

Python Document
0 stars 0 forks source link

18-Shallow copy and Deep copy #18

Open Pin-Jiun opened 1 year ago

Pin-Jiun commented 1 year ago

型別

C語言中,系統會為每個變數分配記憶體空間,當改變變數的值時,改變的是記憶體空間中的值,變數的地址是不改變的。 然而python採用的是基於值的管理方式

a = [1,2]
b = a
print ('a: ', a, 'id(a): ', id(a))
print ('b: ', b, 'id(a): ', id(b))
a:  [1, 2] id(a):  2805258019400
b:  [1, 2] id(a):  2805258019400

可以發現a和b的記憶體地址相同,也就是說,a和b是完全相同的,b只是a的一個引用(也就是一個別名)

python中數據類型分為可變與不可變型別:

可變型別有:列表,字典 不可變型別有:數字,字串,元組

可變物件:該物件所指向記憶體中的值可以被改變 不可變物件:該物件所指向記憶體中的值不可以被改變,所以當變數指向的值改變時,等於將原來的值複製一份後存於一個新的地址,變數再指向這個新的地址

在 list 中使用等號 = 賦值時,由於list為可變物件,實際行為是建立該list的引用(別名)

#%% list copy pass by reference
a = [1,2,3]
a_ref = a
a.append(4)
print("a: ", a)
print("a_ref: ", a)

由上述程式碼可知 a, a_ref 是完全相同的(a_ref 只是 a 的引用) a 和 a_ref 的記憶體位置相同, 對 a 做修改,a_ref 也會被改變

由於a_ref為a的引用,指向的記憶體位置相同,所以在修改a_ref時也會一併修改到a


淺複製與深複製 Shallow copy and deep copy

淺複製僅複製容器中元素的地址 深複製完全複製了一份副本,容器與容器中的元素地址都不一樣


Shallow copy

#%% list copy
a_list = list(a)
a_index = a[:]
a_copy = a.copy()
a.append(5)
print("Shallow copy")
print("a_list: ", a_list)
print("a_index: ", a_index)
print("a_copy: ", a_copy)

淺覆制意味著新列表中的元素是原始列表中元素的引用。因此,如果原始列表包含可變對象(如列表或字典),那麽這些對象的更改將在新列表中反映出來。但是,如果修改了原始列表的對象本身(例如,修改了嵌套列表中的元素),則不會影響到新列表。


深複製 deep copy

需要import copy模組,裡面有deepcopy函式可以用

import copy
a = [1, [2,3]]
a_deepcopy = copy.deepcopy(a)

參考網址 https://ithelp.ithome.com.tw/articles/10221255 https://www.796t.com/content/1544614591.html

Pin-Jiun commented 4 months ago

以下是證明list.copy()是淺複製的例子:


# 原始列表
original_list = [1, 2, [3, 4]]

# 進行淺複製
copied_list = original_list.copy()

# 修改淺複製後的列表中的元素
copied_list[0] = 5
copied_list[2][0] = 6

# 打印兩個列表
print("Original List:", original_list)
print("Copied List:", copied_list)
Original List: [1, 2, [6, 4]]
Copied List: [5, 2, [6, 4]]