深拷貝淺拷貝

2022-07-23 03:54:14 字數 3905 閱讀 7513

不可變物件:該物件所指向的記憶體中的值不能被改變,修改物件的值時,由於其指向的值不能被改變,因此實際上是在記憶體中重新開闢乙個位址用來儲存新的值,然後將物件指向這個新值。本質上是兩個物件,賦值前後物件id發生了變化。python中的不可變物件包括:bool、int、str、float、tuple、frozenset、none。

淺拷貝:通常指構造乙個新的集合物件,然後用原始物件中的找到的子物件的引用來填充它。淺層的複製只有一層深度,複製過程中不會遞迴,所以不會建立子物件本身的副本。

案例1

import copy

lst = [[1,2],3,4]

new3_lst = copy.copy(lst)

print(id(lst), lst) # 2027983558024 [[1, 2], 3, 4]

print(id(new3_lst), new3_lst) # 2027983557000 [[1, 2], 3, 4]

==>先列印一下剛複製出來的兩個物件及記憶體編號

print('-------------------')

new3_lst[0][0] = 4

print(id(lst),lst) # 2027983558024 [[4, 2], 3, 4]

print(id(new3_lst),new3_lst) # 2027983557000 [[4, 2], 3, 4]

==>推出:改變拷貝物件的子物件的成員值,會同時影響原始物件和拷貝物件

print('-------------------')

new3_lst[2] = 0

print(id(lst),lst) # 2757271180296 [[4, 2], 3, 4]

print(id(new3_lst),new3_lst) # 2757271135560 [[4, 2], 3, 0]

==>推出:改變拷貝物件的第一層次的成員值,不會影響原始物件

print('-------------------')

lst[2] = 0

print(id(lst),lst) # 2757271180296 [[4, 2], 3, 0]

print(id(new3_lst),new3_lst) # 2757271135560 [[4, 2], 3, 0]

print('-------------------')

lst[0][0] = 9

print(id(lst),lst) # 2757271180296 [[9, 2], 3, 0]

print(id(new3_lst),new3_lst) # 2757271135560 [[9, 2], 3, 0]

==>推出:改變原始物件的成員或者子物件的成員值,拷貝物件的元素跟著改變

"""總結

淺拷貝,改變原始物件的成員或者子物件的成員值,拷貝物件的元素跟著改變

改變拷貝物件的子物件的成員值,會同時影響原始物件和拷貝物件

改變拷貝物件的第一層次的成員值,不會影響原始物件

"""

案例2

# example 1

lst = [[1,2],3,4]

new2_lst = list(lst)

print(id(lst)) # 2291852075656

print(id(new2_lst)) # 2291852075656

print('-------------------')

new2_lst[0][0] = 40

print(id(lst),lst) # 2364733153992 [[40, 2], 3, 4]

print(id(new2_lst),new2_lst) # 2364736713480 [[40, 2], 3, 4]

print('-------------------')

new2_lst[2] = 40

print(id(lst),lst) # 2364733153992 [[40, 2], 3, 4]

print(id(new2_lst),new2_lst) # 2364736713480 [[40, 2], 3, 40]

print('***********************')

lst[0][1] = 20

print(id(lst),lst) # 2364733153992 [[40, 20], 3, 4]

print(id(new2_lst),new2_lst) # 2364736713480 [[40, 20], 3, 40]

print('-------------------')

lst[2] = 30

print(id(lst),lst) # 2364733153992 [[40, 20], 3, 30]

print(id(new2_lst),new2_lst) # 2364736713480 [[40, 20], 3, 40]

"""總結

修改第一層次的成員值,不會影響拷貝物件;修改子物件的成員值(第二層次),會同時影響原始物件和拷貝物件

"""

深拷貝:深拷貝使複製過程遞迴,即首先構造乙個新的集合物件,然後遞迴地用在原始物件中找到的子物件的副本來填充它。通過深拷貝複製物件,是原始物件及其所有子物件的完全獨立的轉殖。

# 深拷貝: 拷貝物件及子物件(遞迴)

lst1 = [[1,2],3,4]

print('--------深拷貝--------')

import copy

new4_lst = copy.deepcopy(lst1)

print(id(lst1),lst1) # 1951550628552 [[1, 2], 3, 4]

print(id(new4_lst),new4_lst) # 1951582564552 [[1, 2], 3, 4]

==>先列印一下剛深拷貝出來的兩個物件及記憶體編號

print('-------------------')

# 改變新物件的子物件的成員值,不會影響原始物件

new4_lst[0][1] = 9

print(id(lst1),lst1) # 1951550628552 [[1, 2], 3, 4]

print(id(new4_lst),new4_lst) # 1951582564552 [[1, 9], 3, 4]

print('-------------------')

# 改變拷貝物件的第一層次的成員值,不會影響原始物件

new4_lst[1] = 10

print(id(lst1),lst1) # 1951550628552 [[1, 2], 3, 4]

print(id(new4_lst),new4_lst) # 1951582564552 [[1, 9], 10, 4]

print('-------------------')

# 改變原始物件的子物件的成員值,不會影響拷貝物件

lst1[0][1] = 20

print(id(lst1),lst1) # 1951550628552 [[1, 20], 3, 4]

print(id(new4_lst),new4_lst) # 1951582564552 [[1, 9], 10, 4]

print('-------------------')

# 改變原始物件的第一層次的成員值,不會影響拷貝物件

lst1[1] = 16

print(id(lst1),lst1) # 1951550628552 [[1, 20], 16, 4]

print(id(new4_lst),new4_lst) # 1951582564552 [[1, 9], 10, 4]

"""總結

深拷貝,新舊對像及其子物件的成員值完全獨立,互不影響

"""

總結

淺拷貝 深拷貝

copy mutablecopy copy 不管是可變的,還是不可變的,結果都是不可變的 mutablecopy 不管是不可變的,還是可變的,結果都是可變的 nsmutablestring str nsmutablestring stringwithformat a nsarray arr1 str...

深拷貝 淺拷貝

c 中物件的複製就如同 轉殖 用乙個已有的物件快速地複製出多個完全相同的物件。一般而言,以下三種情況都會使用到物件的複製 1 建立乙個新物件,並用另乙個同類的已有物件對新物件進行初始化,例如 cpp view plain copy class rect rect rect1 rect rect2 r...

淺拷貝 深拷貝

retain是建立乙個指標,引用物件計數加1。copy屬性表示兩個物件內容相同,新的物件retain為1 與舊有物件的引用計數無關,舊有物件沒有變化。copy減少物件對上下文的依賴。retain屬性表示兩個物件位址相同 建立乙個指標,指標拷貝 內容當然相同,這個物件的retain值 1也就是說,re...