最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文帶你掌握Python中的深淺拷貝

 更新時間:2026年01月13日 09:33:57   作者:小莊-Python辦公  
本文將深入解析Python中的深淺拷貝問題,通過實例演示賦值,淺拷貝和深拷貝的區(qū)別,這篇文章剖析了字典.copy()方法的誤區(qū),并給出最佳實踐建議,希望對大家有所幫助

第一章:一切從“賦值”引發(fā)的問題開始

在 Python 的世界里,變量不僅僅是存儲數(shù)據(jù)的標簽,更像是指向內(nèi)存中某個對象的“指針”。很多初學者,甚至是有一定經(jīng)驗的開發(fā)者,都曾在深淺拷貝的問題上栽過跟頭。

想象一個場景:你有一個列表,里面包含了一些子列表,你想復制一份用來做修改,保留原數(shù)據(jù)。于是你順手寫了這樣一行代碼:

original_list = [[1, 2], [3, 4]]
new_list = original_list

# 現(xiàn)在,我想修改 new_list 的第一個子列表
new_list[0][0] = 999

print("Original:", original_list)
print("New:", new_list)

如果你的預期是 Original 保持 [[1, 2], [3, 4]],而 New 變?yōu)?[[999, 2], [3, 4]],那么很遺憾,現(xiàn)實會給你沉重一擊。運行結(jié)果是:

Original: [[999, 2], [3, 4]]
New: [[999, 2], [3, 4]]

為什么?

這就是 Python 中最基礎(chǔ)但也最容易被忽視的概念:賦值(Assignment)并不是拷貝。

在上面的代碼中,new_list = original_list 并沒有創(chuàng)建一個新的列表對象,它僅僅是創(chuàng)建了一個新的引用(reference)。這就好比你有兩個名字(original_listnew_list),但它們都指向同一個實體(內(nèi)存中的列表對象)。因此,通過任何一個名字去修改這個實體,另一個名字看到的自然也是修改后的樣子。

為了徹底解決這個問題,我們需要深入理解 Python 內(nèi)存模型中的三個層次:賦值、淺拷貝和深拷貝。

第二章:淺拷貝(Shallow Copy)——“只復制第一層”

當我們意識到直接賦值不是復制時,我們通常會轉(zhuǎn)向淺拷貝。在 Python 中,實現(xiàn)淺拷貝的方法有很多:

  • 切片操作:new_list = old_list[:]
  • 工廠函數(shù):new_list = list(old_list)
  • copy 模塊:import copy; new_list = copy.copy(old_list)

讓我們看看淺拷貝的表現(xiàn):

import copy

original_list = [[1, 2], [3, 4]]
shallow_copied_list = copy.copy(original_list)

# 修改外層
shallow_copied_list.append([5, 6])

# 修改內(nèi)層(嵌套對象)
shallow_copied_list[0][0] = 888

print("Original:", original_list)
print("Shallow:", shallow_copied_list)

輸出結(jié)果:

Original: [[888, 2], [3, 4]]
Shallow: [[888, 2], [3, 4], [5, 6]]

分析:

  • 外層修改shallow_copied_list 增加了一個元素 [5, 6]original_list 沒變。這說明最外層的容器確實是新創(chuàng)建的。
  • 內(nèi)層修改shallow_copied_list[0][0] 被改為 888,original_list 也跟著變了。這說明內(nèi)層的子列表并沒有被復制。

什么是淺拷貝?

淺拷貝(Shallow Copy)會創(chuàng)建一個新的容器對象,但不會遞歸地復制容器內(nèi)的元素。新容器中填充的是原容器中元素的引用。

對于不可變對象(如整數(shù)、字符串、元組),引用就引用吧,反正改不了。但如果你的列表里包含了可變對象(如列表、字典、集合),那么這些可變對象的引用被共享了,這就是所謂的“共享子對象”(Shared Sub-objects)。

適用場景:淺拷貝適用于你的數(shù)據(jù)結(jié)構(gòu)是“扁平”的,或者你明確知道你需要共享子對象(這很少見)。

第三章:深拷貝(Deep Copy)——“斬斷所有羈絆”

如果你需要一個完全獨立的副本,無論嵌套多少層,修改副本都不影響原件,那么你需要的是深拷貝。

深拷貝使用 copy.deepcopy() 實現(xiàn):

import copy

original_list = [[1, 2], [3, 4]]
deep_copied_list = copy.deepcopy(original_list)

# 徹底修改副本
deep_copied_list[0][0] = 777
deep_copied_list.append([9, 0])

print("Original:", original_list)
print("Deep:", deep_copied_list)

輸出結(jié)果:

Original: [[1, 2], [3, 4]]
Deep: [[777, 2], [3, 4], [9, 0]]

什么是深拷貝?

深拷貝會遞歸地遍歷原對象的所有子對象,并創(chuàng)建它們的副本。這意味著新對象和原對象在內(nèi)存中是完全獨立的,沒有任何引用重疊。

深拷貝的陷阱與高級用法:

雖然深拷貝很強大,但它也有代價(性能開銷大)和陷阱。

遞歸引用導致死循環(huán)

如果一個對象直接或間接引用了自己,deepcopy 會拋出 RecursionError。

a = [1]
a.append(a) # a 現(xiàn)在是 [1, [...]]
# b = copy.deepcopy(a) # 這會報錯

自定義類的拷貝控制:如果你需要控制類的深拷貝行為,可以實現(xiàn) __deepcopy__ 方法。這在處理數(shù)據(jù)庫連接、文件句柄等不可序列化或不可拷貝的資源時非常有用。

性能考量:對于巨大的數(shù)據(jù)結(jié)構(gòu),深拷貝可能非常慢。如果你的嵌套層級很淺,或者全是不可變數(shù)據(jù),深拷貝就是殺雞用牛刀。

第四章:核心原理圖解與常見誤區(qū)

為了徹底理清關(guān)系,我們可以通過一張簡化的內(nèi)存示意圖來理解:

假設(shè) a = [1, [2, 3]]

賦值 (b = a):

  • a -> [ptr1, ptr2]
  • b -> [ptr1, ptr2] (指向同一個地址)

淺拷貝 (b = copy.copy(a)):

  • a -> [ptr1, ptr2]
  • b -> [ptr3, ptr4]
  • 其中 ptr1 == ptr3 (指向同一個整數(shù) 1,整數(shù)不可變所以無所謂)
  • 但是 ptr2 == ptr4 (指向同一個列表 [2, 3]) -> 這是問題的根源

深拷貝 (b = copy.deepcopy(a)):

  • a -> [ptr1, ptr2]
  • b -> [ptr5, ptr6]
  • ptr5 指向新的整數(shù) 1
  • ptr6 指向一個新的列表 [2, 3],且該新列表內(nèi)的元素也是新的。

常見誤區(qū):字典的copy()方法

很多 Python 開發(fā)者會直接用字典自帶的 .copy() 方法,認為這就是深拷貝。

錯誤! 字典的 .copy() 也是淺拷貝!

d1 = {'a': [1, 2]}
d2 = d1.copy()
d2['a'].append(3)

print(d1) # 輸出 {'a': [1, 2, 3]},d1 被修改了!

正確的做法依然是 copy.deepcopy(d1) 或者使用 d1.copy() 配合字典推導式(如果只有一層的話)。

第五章:總結(jié)與最佳實踐

搞懂了深淺拷貝,我們其實是在搞懂 Python 的對象引用模型。這是編寫健壯、無副作用代碼的基石。

最后的建議:

  • 默認使用引用:除非你明確需要副本,否則不要隨意拷貝。
  • 優(yōu)先考慮淺拷貝:如果數(shù)據(jù)結(jié)構(gòu)是扁平的,或者你確定不需要處理嵌套可變對象,list[:]copy.copy() 更快。
  • 不確定時用深拷貝:對于復雜的嵌套結(jié)構(gòu),為了數(shù)據(jù)的安全性,copy.deepcopy() 是最穩(wěn)妥的選擇。
  • 警惕函數(shù)副作用:在函數(shù)中修改傳入的可變參數(shù)時,一定要想清楚這是不是你想要的行為。如果不想修改原數(shù)據(jù),記得在函數(shù)內(nèi)部先拷貝。

以上就是一文帶你掌握Python中的深淺拷貝的詳細內(nèi)容,更多關(guān)于Python深淺拷貝的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • python 一維二維插值實例

    python 一維二維插值實例

    這篇文章主要介紹了python 一維二維插值實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04
  • Python利用Charles 實現(xiàn)全部自動答題思路流程分析

    Python利用Charles 實現(xiàn)全部自動答題思路流程分析

    這篇文章主要介紹了Python利用Charles 實現(xiàn)全部自動答題思路流程分析,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-08-08
  • python 隨機森林算法及其優(yōu)化詳解

    python 隨機森林算法及其優(yōu)化詳解

    這篇文章主要介紹了ptyhon 隨機森林算法及其優(yōu)化詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-07-07
  • python flask sqlalchemy連接數(shù)據(jù)庫流程介紹

    python flask sqlalchemy連接數(shù)據(jù)庫流程介紹

    這篇文章主要介紹了python flask sqlalchemy連接數(shù)據(jù)庫流程,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-09-09
  • Python Pandas 獲取列匹配特定值的行的索引問題

    Python Pandas 獲取列匹配特定值的行的索引問題

    這篇文章主要介紹了Python Pandas 獲取列匹配特定值的行的索引問題,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-07-07
  • python pyautogui實現(xiàn)圖片識別點擊失敗后重試功能

    python pyautogui實現(xiàn)圖片識別點擊失敗后重試功能

    這篇文章主要介紹了python pyautogui實現(xiàn)圖片識別點擊失敗后重試效果,本文通過實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-06-06
  • OpenCV中Canny邊緣檢測的實現(xiàn)

    OpenCV中Canny邊緣檢測的實現(xiàn)

    本文主要介紹了OpenCV中Canny邊緣檢測的實現(xiàn),邊緣檢測一般是識別目標圖像中亮度變化明顯的像素點,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Python解析json時提示“string indices must be integers”問題解決方法

    Python解析json時提示“string indices must be integers”問題解決方法

    這篇文章主要介紹了Python解析json時提示“string indices must be integers”問題解決方法,結(jié)合實例形式分析了Python解析json字符串操作規(guī)范與相關(guān)使用技巧,需要的朋友可以參考下
    2019-07-07
  • python線程join方法原理解析

    python線程join方法原理解析

    這篇文章主要介紹了python線程join方法原理解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-02-02
  • Python打印特殊符號及對應(yīng)編碼解析

    Python打印特殊符號及對應(yīng)編碼解析

    這篇文章主要介紹了Python打印特殊符號及對應(yīng)編碼解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-05-05

最新評論

滁州市| 军事| 渝中区| 绥德县| 交口县| 股票| 昌吉市| 曲靖市| 保山市| 富民县| 威远县| 方正县| 延川县| 灌云县| 波密县| 诸暨市| 都匀市| 安徽省| 澎湖县| 灵山县| 内黄县| 观塘区| 武汉市| 南雄市| 托克逊县| 安福县| 新民市| 开阳县| 洛南县| 盖州市| 佛学| 赤城县| 翁牛特旗| 穆棱市| 泗水县| 文化| 文成县| 乌拉特后旗| 建平县| 财经| 祁连县|