佳木斯湛栽影视文化发展公司

主頁(yè) > 知識(shí)庫(kù) > Python列表的深復(fù)制和淺復(fù)制示例詳解

Python列表的深復(fù)制和淺復(fù)制示例詳解

熱門標(biāo)簽:企業(yè)做大做強(qiáng) Win7旗艦版 百度AI接口 客戶服務(wù) 硅谷的囚徒呼叫中心 呼叫中心市場(chǎng)需求 語(yǔ)音系統(tǒng) 電話運(yùn)營(yíng)中心

一、深復(fù)制與淺復(fù)制

列表是Python中自帶的一種數(shù)據(jù)結(jié)構(gòu),在使用列表時(shí),拷貝操作不可避免,下面簡(jiǎn)單討論一下列表的深復(fù)制(拷貝)與淺復(fù)制

首先看代碼:

l1 = [5, 4, 3, 2, 1]
# 用兩種方法實(shí)現(xiàn)對(duì)列表l1的拷貝
l2 = l1
l3 = l1[:]
print(l1) # [5, 4, 3, 2, 1]
print(l2) # [5, 4, 3, 2, 1]
print(l3) # [5, 4, 3, 2, 1]
 
#修改l1
l1[0] = 9
print(l1) # [9, 4, 3, 2, 1]
print(l2) # [9, 4, 3, 2, 1]
print(l3) # [5, 4, 3, 2, 1]

我們發(fā)現(xiàn)修改l1的第一個(gè)元素后,l2的第一個(gè)元素跟著改變,而l3并沒(méi)有發(fā)生變化。Python內(nèi)置函數(shù)id()可以返回元素的地址,那么我們使用這個(gè)函數(shù)來(lái)看一下三個(gè)列表的地址:

print(id(l1)) # 2927957162504
print(id(l2)) # 2927957162504
print(id(l3)) # 2927923243528

從結(jié)果來(lái)看,l1和l2地址是一樣的,也就是說(shuō)l1和l2指向的是同一塊內(nèi)存區(qū)域,顯然,通過(guò) l2 = l1 操作,l1和l2都成了指向同一塊內(nèi)存地址的“指針”,也就是說(shuō)這個(gè)操作是為l1取了一個(gè)別名,也可以說(shuō)l2是l1的一個(gè)引用。用一張圖來(lái)解釋:

那么修改l1也就是在修改l2:

接下來(lái)看一下創(chuàng)建l3的過(guò)程,l3 = l1[:] ,這是將l1進(jìn)行切片,并將切片后的列表拷貝到l3所指向的內(nèi)存區(qū)域,同樣看圖:

也就是說(shuō)l1和l3指向不同的內(nèi)存區(qū)域,那么修改l1并不會(huì)影響到l3:

通俗的來(lái)講,像l2這種,拷貝出來(lái)的對(duì)象和原對(duì)象的地址相同,為淺復(fù)制,像l3這種,分配新的內(nèi)存空間并拷貝原始內(nèi)容的,拷貝出來(lái)的對(duì)象和原對(duì)象的地址不同,為深復(fù)制

二、復(fù)制列表內(nèi)元素的淺復(fù)制

在復(fù)制列表中的所有元素的時(shí)候,進(jìn)行淺復(fù)制

看一個(gè)比較有意思的東西,看代碼:

l1 = [1,2,3,[1,3]]
l2 = l1[:]
l1[3][1] = 9
print(l1) # [1, 2, 3, [1, 9]]
print(l2) # [1, 2, 3, [1, 9]]

按照前面的理解,修改l1某個(gè)元素后,l2應(yīng)該不會(huì)發(fā)生改變,可結(jié)果卻與我們預(yù)想的結(jié)果大相徑庭,于是,我們不得不思考一下l2深復(fù)制到底復(fù)制了什么東西。實(shí)際上列表其實(shí)可以理解為一個(gè)“指針”,l1[3]是一個(gè)列表元素,l2[3]也是一個(gè)列表元素,執(zhí)行以下代碼:

print(id(l2[3])) # 2014816956232
print(id(l1[3])) # 2014816956232

我們發(fā)現(xiàn)l1[3]和l2[3]指向的地址是一樣的,也就是說(shuō)在執(zhí)行 l2 = l1[:] 的時(shí)候,將一個(gè)地址拷貝了,所以修改l1[3]相當(dāng)于修改l2[3],所以才會(huì)出現(xiàn)上述結(jié)果,這更加說(shuō)明了列表其實(shí)就是一個(gè)指向一片內(nèi)存區(qū)域的“指針”。那么我們是不是可以說(shuō)列表l2深復(fù)制l1,但是對(duì)列表中每個(gè)元素進(jìn)行復(fù)制時(shí)進(jìn)行的是淺復(fù)制呢?答案顯而易見(jiàn)。

修改l1[3]中的元素:

三、copy()和deepcopy()

copy模塊可以幫助我們實(shí)現(xiàn)對(duì)象的復(fù)制操作

列舉一下其他的拷貝列表的方式:

l4 = l1 * 1
print(id(l4)) # 2927957916296
l5 = list(l1)
print(id(l5)) # 2927957767816
import copy
l6 = copy.copy(l1)
print(id(l6)) # 2927956854024
l7 = copy.deepcopy(l1)
print(id(l7)) # 2927958503368

我們可以看到,這幾種拷貝方式所得到的的新對(duì)象與原對(duì)象的地址都不相同了,并沒(méi)有按照字面意思(copy進(jìn)行淺復(fù)制,deepcopy進(jìn)行深復(fù)制),那么copy()和deepcopy()究竟有什么區(qū)別呢,繼續(xù)看代碼:

list1 = [1,2,3,[1,3]]
list2 = list1[:]
list3 = copy.copy(list1)
list4 = copy.deepcopy(list1)
list1[3][0] = 9
print(list1) # [1, 2, 3, [9, 3]]
print(list2) # [1, 2, 3, [9, 3]]
print(list3) # [1, 2, 3, [9, 3]]
print(list4) # [1, 2, 3, [1, 3]]
print(id(list1[3])) # 2927923172616
print(id(list2[3])) # 2927923172616
print(id(list3[3])) # 2927923172616
print(id(list4[3])) # 2927967190728

可以發(fā)現(xiàn)copy()和前面提到的用 [:] 進(jìn)行拷貝沒(méi)有本質(zhì)上的區(qū)別,對(duì)列表中的每個(gè)元素進(jìn)行復(fù)制時(shí)進(jìn)行的是淺拷貝,而deepcopy()在復(fù)制列表中的每個(gè)元素的時(shí)候,進(jìn)行的是深拷貝

總結(jié)

到此這篇關(guān)于Python列表的深復(fù)制和淺復(fù)制的文章就介紹到這了,更多相關(guān)Python列表深復(fù)制和淺復(fù)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • python函數(shù)調(diào)用,循環(huán),列表復(fù)制實(shí)例
  • 詳解Python列表賦值復(fù)制深拷貝及5種淺拷貝
  • python復(fù)制列表時(shí)[:]和[::]之間有什么區(qū)別
  • python 合并列表的八種方法
  • python中列表(list)和元組(tuple)的深入講解
  • Python 實(shí)現(xiàn)把列表中的偶數(shù)變成他的平方
  • Python 列表(List)的底層實(shí)現(xiàn)原理分析
  • Python基礎(chǔ)詳解之列表復(fù)制

標(biāo)簽:山西 濟(jì)南 長(zhǎng)沙 崇左 安康 山西 海南 喀什

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Python列表的深復(fù)制和淺復(fù)制示例詳解》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    镇巴县| 油尖旺区| 泾川县| 崇信县| 辽源市| 建平县| 广河县| 沅江市| 霍州市| 水富县| 定襄县| 台东县| 邛崃市| 巴彦县| 临武县| 博湖县| 绥中县| 漯河市| 汉中市| 正镶白旗| 沈阳市| 龙游县| 牟定县| 象州县| 惠州市| 临桂县| 临夏市| 广东省| 沙田区| 绥阳县| 宁陵县| 青岛市| 固阳县| 平罗县| 汝南县| 教育| 镇赉县| 闽清县| 墨竹工卡县| 黔江区| 唐海县|