python的深淺copy詳解(python深淺複製)

本文目錄一覽:

python深拷貝和淺拷貝的區別

淺拷貝是對一個對象父級(外層)的拷貝,並不會拷貝子級(內部),而深拷貝對一個對象是所有層次的拷貝(遞歸),內部和外部都會被拷貝過來。

使用淺拷貝的時候,分為兩種情況。

第一種,如果最外層的數據類型是可變的,比如說列表,字典等,淺拷貝會開啟新的地址空間去存放。

第二種,如果最外層的數據類型是不可變的,比如元組,字符串等,淺拷貝對象的時候,還是引用對象的地址空間。

深拷貝也分兩種情況:

第一種,最外層數據類型可變。這個時候,內部和外部的都會拷貝過來。

第二種,外層數據類型不可變,如果裡面是可變數據類型,會新開闢地址空間存放。如果內部數據類型不可變,才會如同淺拷貝一樣,是對地址的引用。

Python裡面如何拷貝一個對象?(賦值,淺拷貝,深拷貝的區別)

賦值(=):就是創建了對象的一個新的引用,修改其中任意一個變量都會影響到另一個。

淺拷貝:創建一個新的對象,但它包含的是對原始對象中包含項的引用(如果用引用的方式修改其中一個對象,另外一個也會修改改變){1,完全切片方法;2,工廠函數,如list();3,copy模塊的copy()函數}

深拷貝:創建一個新的對象,並且遞歸的複製它所包含的對象(修改其中一個,另外一個不會改變){copy模塊的deep.deepcopy()函數}

Python中的賦值,淺拷貝和深拷貝的區別

賦值(=),就是創建了對象的一個新的引用,修改其中任意一個變量都會影響到另一個。

淺拷貝:創建一個新的對象,但它包含的是對原始對象中包含項的引用(如果用引用的方式修改其中一個對象,另外一個也會修改改變){1,完全切片方法;2,工廠函數,如list();3,copy模塊的copy()函數}

深拷貝:創建一個新的對象,並且遞歸的複製它所包含的對象(修改其中一個,另外一個不會改變){copy模塊的deep.deepcopy()函數}

python 為什麼有深拷貝淺拷貝

在寫Python過程中,經常會遇到對象的拷貝,如果不理解淺拷貝和深拷貝的概念,你的代碼就可能出現一些問題。所以,在這裡按個人的理解談談它們之間的區別。

一、賦值(assignment)

在《Python FAQ1》一文中,對賦值已經講的很清楚了,關鍵要理解變量與對象的關係。

12345

a = [1, 2, 3] b = a print(id(a), id(b), sep=’\n’)139701469405552139701469405552

在Python中,用一個變量給另一個變量賦值,其實就是給當前內存中的對象增加一個“標籤”而已。

如上例,通過使用內置函數 id() ,可以看出 a 和 b 指向內存中同一個對象。a is b會返回 True 。

二、淺拷貝(shallow copy)

注意:淺拷貝和深拷貝的不同僅僅是對組合對象來說,所謂的組合對象就是包含了其它對象的對象,如列表,類實例。而對於數字、字符串以及其它“原子”類型,沒有拷貝一說,產生的都是原對象的引用。

所謂“淺拷貝”,是指創建一個新的對象,其內容是原對象中元素的引用。(拷貝組合對象,不拷貝子對象)

常見的淺拷貝有:切片操作、工廠函數、對象的copy()方法、copy模塊中的copy函數。

12345678910

a = [1, 2, 3] b = list(a) print(id(a), id(b)) # a和b身份不同140601785066200 140601784764968 for x, y in zip(a, b): # 但它們包含的子對象身份相同… print(id(x), id(y))… 140601911441984 140601911441984140601911442016 140601911442016140601911442048 140601911442048

從上面可以明顯的看出來,a 淺拷貝得到 b,a 和 b 指向內存中不同的 list 對象,但它們的元素卻指向相同的 int 對象。這就是淺拷貝!

三、深拷貝(deep copy)

所謂“深拷貝”,是指創建一個新的對象,然後遞歸的拷貝原對象所包含的子對象。深拷貝出來的對象與原對象沒有任何關聯。

深拷貝只有一種方式:copy模塊中的deepcopy函數。

1234567891011

import copy a = [1, 2, 3] b = copy.deepcopy(a) print(id(a), id(b))140601785065840 140601785066200 for x, y in zip(a, b):… print(id(x), id(y))… 140601911441984 140601911441984140601911442016 140601911442016140601911442048 140601911442048

看了上面的例子,有人可能會疑惑:

為什麼使用了深拷貝,a和b中元素的id還是一樣呢?

答:這是因為對於不可變對象,當需要一個新的對象時,python可能會返回已經存在的某個類型和值都一致的對象的引用。而且這種機制並不會影響 a 和 b 的相互獨立性,因為當兩個元素指向同一個不可變對象時,對其中一個賦值不會影響另外一個。

我們可以用一個包含可變對象的列表來確切地展示“淺拷貝”與“深拷貝”的區別:

1234567891011121314151617181920

import copy a = [[1, 2],[5, 6], [8, 9]] b = copy.copy(a) # 淺拷貝得到b c = copy.deepcopy(a) # 深拷貝得到c print(id(a), id(b)) # a 和 b 不同139832578518984 139832578335520 for x, y in zip(a, b): # a 和 b 的子對象相同… print(id(x), id(y))… 139832578622816 139832578622816139832578622672 139832578622672139832578623104 139832578623104 print(id(a), id(c)) # a 和 c 不同139832578518984 139832578622456 for x, y in zip(a, c): # a 和 c 的子對象也不同… print(id(x), id(y))… 139832578622816 139832578621520139832578622672 139832578518912139832578623104 139832578623392

從這個例子中可以清晰地看出淺拷貝與深拷貝地區別。

總結:

1、賦值:簡單地拷貝對象的引用,兩個對象的id相同。

2、淺拷貝:創建一個新的組合對象,這個新對象與原對象共享內存中的子對象。

3、深拷貝:創建一個新的組合對象,同時遞歸地拷貝所有子對象,新的組合對象與原對象沒有任何關聯。雖然實際上會共享不可變的子對象,但不影響它們的相互獨立性。

淺拷貝和深拷貝的不同僅僅是對組合對象來說,所謂的組合對象就是包含了其它對象的對象,如列表,類實例。而對於數字、字符串以及其它“原子”類型,沒有拷貝一說,產生的都是原對象的引用。

舉例區分Python中的淺複製與深複製

舉例區分Python中的淺複製與深複製

這篇文章主要介紹了舉例區分Python中的淺複製與深複製,是Python入門學習中的重要知識,需要的朋友可以參考下

copy模塊用於對象的拷貝操作。該模塊非常簡單,只提供了兩個主要的方法: copy.copy 與 copy.deepcopy ,分別表示淺複製與深複製。什麼是淺複製,什麼是深複製,網上有一卡車一卡車的資料,這裡不作詳細介紹。複製操作只對複合對象有效。用簡單的例子來分別介紹這兩個方法。

淺複製只複製對象本身,沒有複製該對象所引用的對象。

#coding=gbk

import copy

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

l2 = copy.copy(l1)

print l1

print l2

l2[2][0] = 50

print l1

print l2

#—- 結果 —-

[1, 2, [3, 4]]

[1, 2, [3, 4]]

[1, 2, [50, 4]]

[1, 2, [50, 4]]

同樣的代碼,使用深複製,結果就不一樣:

import copy

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

l2 = copy.deepcopy(l1)

print l1

print l2

l2[2][0] = 50

print l1

print l2

#—- 結果 —-

[1, 2, [3, 4]]

[1, 2, [3, 4]]

[1, 2, [3, 4]]

[1, 2, [50, 4]]

改變copy的默認行為

在定義類的時候,通過定義__copy__和__deepcopy__方法,可以改變copy的默認行為。下面是一個簡單的例子:

class CopyObj(object):

def __repr__(self):

return “CopyObj”

def __copy__(self):

return “Hello”

obj = CopyObj()

obj1 = copy.copy(obj)

print obj

print obj1

#—- 結果 —-

CopyObj

Hello

python的複製,深拷貝和淺拷貝的區別

這個問題其實網上解答已經很多了,最好說仔細點在什麼地方不理解。

下面一個例子可以看看:

import copy

a = [1, 2, 3, 4, [‘a’, ‘b’]] #原始對象

b = a #賦值,傳對象的引用

c = copy.copy(a) #對象拷貝,淺拷貝

d = copy.deepcopy(a) #對象拷貝,深拷貝

a.append(5) #修改對象a

a[4].append(‘c’) #修改對象a中的[‘a’, ‘b’]數組對象

print ‘a = ‘, a

print ‘b = ‘, b

print ‘c = ‘, c

print ‘d = ‘, d

然後自己想一想輸出都應該是什麼

a是原始對象,作為對照

b是a的引用,和a指向同一個對象

c是a的一個淺拷貝,將a的內容拷貝過來了,就是和a平行的兩個對象了,但是裡面元素如果是對象,僅拷貝其引用,即a[4]變化後c[4]也對應變化了,因為他倆實際指向同一個對象,而a和c指向不同的對象

d則是從頭到尾全部拷貝過來,就連裡面的對象也拷貝了一份,因此a[4]變化而d[4]沒有變化,因為a[4]和d[4]在拷貝的時候值一樣,但是其實已經是兩個對象了。

下面是上面內容的輸出結果。

a = [1, 2, 3, 4, [‘a’, ‘b’, ‘c’], 5]

b = [1, 2, 3, 4, [‘a’, ‘b’, ‘c’], 5]

c = [1, 2, 3, 4, [‘a’, ‘b’, ‘c’]]

d = [1, 2, 3, 4, [‘a’, ‘b’]]

原創文章,作者:BVZK,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/135917.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
BVZK的頭像BVZK
上一篇 2024-10-04 00:15
下一篇 2024-10-04 00:15

相關推薦

  • Python列表中負數的個數

    Python列表是一個有序的集合,可以存儲多個不同類型的元素。而負數是指小於0的整數。在Python列表中,我們想要找到負數的個數,可以通過以下幾個方面進行實現。 一、使用循環遍歷…

    編程 2025-04-29
  • Python中引入上一級目錄中函數

    Python中經常需要調用其他文件夾中的模塊或函數,其中一個常見的操作是引入上一級目錄中的函數。在此,我們將從多個角度詳細解釋如何在Python中引入上一級目錄的函數。 一、加入環…

    編程 2025-04-29
  • Python周杰倫代碼用法介紹

    本文將從多個方面對Python周杰倫代碼進行詳細的闡述。 一、代碼介紹 from urllib.request import urlopen from bs4 import Bea…

    編程 2025-04-29
  • 如何查看Anaconda中Python路徑

    對Anaconda中Python路徑即conda環境的查看進行詳細的闡述。 一、使用命令行查看 1、在Windows系統中,可以使用命令提示符(cmd)或者Anaconda Pro…

    編程 2025-04-29
  • Python計算陽曆日期對應周幾

    本文介紹如何通過Python計算任意陽曆日期對應周幾。 一、獲取日期 獲取日期可以通過Python內置的模塊datetime實現,示例代碼如下: from datetime imp…

    編程 2025-04-29
  • Python清華鏡像下載

    Python清華鏡像是一個高質量的Python開發資源鏡像站,提供了Python及其相關的開發工具、框架和文檔的下載服務。本文將從以下幾個方面對Python清華鏡像下載進行詳細的闡…

    編程 2025-04-29
  • Python程序需要編譯才能執行

    Python 被廣泛應用於數據分析、人工智能、科學計算等領域,它的靈活性和簡單易學的性質使得越來越多的人喜歡使用 Python 進行編程。然而,在 Python 中程序執行的方式不…

    編程 2025-04-29
  • 蝴蝶優化算法Python版

    蝴蝶優化算法是一種基於仿生學的優化算法,模仿自然界中的蝴蝶進行搜索。它可以應用於多個領域的優化問題,包括數學優化、工程問題、機器學習等。本文將從多個方面對蝴蝶優化算法Python版…

    編程 2025-04-29
  • Python字典去重複工具

    使用Python語言編寫字典去重複工具,可幫助用戶快速去重複。 一、字典去重複工具的需求 在使用Python編寫程序時,我們經常需要處理數據文件,其中包含了大量的重複數據。為了方便…

    編程 2025-04-29
  • python強行終止程序快捷鍵

    本文將從多個方面對python強行終止程序快捷鍵進行詳細闡述,並提供相應代碼示例。 一、Ctrl+C快捷鍵 Ctrl+C快捷鍵是在終端中經常用來強行終止運行的程序。當你在終端中運行…

    編程 2025-04-29

發表回復

登錄後才能評論