成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

python深拷貝指的是什么-創(chuàng)新互聯(lián)

創(chuàng)新互聯(lián)www.cdcxhl.cn八線動(dòng)態(tài)BGP香港云服務(wù)器提供商,新人活動(dòng)買多久送多久,劃算不套路!

曲陽(yáng)ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書未來(lái)市場(chǎng)廣闊!成為成都創(chuàng)新互聯(lián)公司的ssl證書銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:13518219792(備注:SSL證書合作)期待與您的合作!

小編給大家分享一下python深拷貝指的是什么,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討吧!

Python 淺拷貝

常見(jiàn)的淺拷貝的方法,是使用數(shù)據(jù)類型本身的構(gòu)造器,比如下面兩個(gè)例子:

list1 = [1, 2, 3]
list2 = list(list1)
print(list2)
print("list1==list2 ?",list1==list2)
print("list1 is list2 ?",list1 is list2)
set1= set([1, 2, 3])
set2 = set(set1)
print(set2)
print("set1==set2 ?",set1==set2)
print("set1 is set2 ?",set1 is set2)

運(yùn)行結(jié)果為:

[1, 2, 3]
list1==list2 ? True
list1 is list2 ? False
{1, 2, 3}
set1==set2 ? True
set1 is set2 ? False

在上面程序中,list2 就是 list1 的淺拷貝,同理 set2 是 set1 的淺拷貝。

當(dāng)然,對(duì)于可變的序列,還可以通過(guò)切片操作符“:”來(lái)完成淺拷貝,例如:

list1 = [1, 2, 3]
list2 = list1[:]
print(list2)
print("list1 == list2 ?",list1 == list2)
print("list1 is list2 ?",list1 is list2)

運(yùn)行結(jié)果為:

[1, 2, 3]
list1 == list2 ? True
list1 is list2 ? False

除此之外,Python 還提供了對(duì)應(yīng)的函數(shù) copy.copy() 函數(shù),適用于任何數(shù)據(jù)類型。其用法如下:

import copy
list1 = [1, 2, 3]
list2 = copy.copy(list1)
print(list2)
print("list1 == list2 ?",list1 == list2)
print("list1 is list2 ?",list1 is list2)

運(yùn)行結(jié)果為:

[1, 2, 3]
list1 == list2 ? True
list1 is list2 ? False

不過(guò)需要注意的是,對(duì)于元組,使用 tuple() 或者切片操作符 ':' 不會(huì)創(chuàng)建一份淺拷貝,相反它會(huì)返回一個(gè)指向相同元組的引用:

tuple1 = (1, 2, 3)
tuple2 = tuple(tuple1)
print(tuple2)
print("tuple1 == tuple2 ?",tuple1 == tuple2)
print("tuple1 is tuple2 ?",tuple1 is tuple2)

運(yùn)行結(jié)果為:

(1, 2, 3)
tuple1 == tuple2 ? True
tuple1 is tuple2 ? True

此程序中,元組 (1, 2, 3) 只被創(chuàng)建一次,t1 和 t2 同時(shí)指向這個(gè)元組。

看到這里,也許你可能對(duì)淺拷貝有了初步的認(rèn)識(shí)。淺拷貝,指的是重新分配一塊內(nèi)存,創(chuàng)建一個(gè)新的對(duì)象,但里面的元素是原對(duì)象中各個(gè)子對(duì)象的引用。

對(duì)數(shù)據(jù)采用淺拷貝的方式時(shí),如果原對(duì)象中的元素不可變,那倒無(wú)所謂;但如果元素可變,淺拷貝通常會(huì)出現(xiàn)一些問(wèn)題,例如:

list1 = [[1, 2], (30, 40)]
list2 = list(list1)
list1.append(100)
print("list1:",list1)
print("list2:",list2)
list1[0].append(3)
print("list1:",list1)
print("list2:",list2)
list1[1] += (50, 60)
print("list1:",list1)
print("list2:",list2)

運(yùn)行結(jié)果為:

list1: [[1, 2], (30, 40), 100]
list2: [[1, 2], (30, 40)]
list1: [[1, 2, 3], (30, 40), 100]
list2: [[1, 2, 3], (30, 40)]
list1: [[1, 2, 3], (30, 40, 50, 60), 100]
list2: [[1, 2, 3], (30, 40)]

此程序中,首先初始化了 list1 列表,包含一個(gè)列表和一個(gè)元組;然后對(duì) list1 執(zhí)行淺拷貝,賦予 list2。因?yàn)闇\拷貝里的元素是對(duì)原對(duì)象元素的引用,因此 list2 中的元素和 list1 指向同一個(gè)列表和元組對(duì)象。

接著往下看,list1.append(100) 表示對(duì) list1 的列表新增元素 100。這個(gè)操作不會(huì)對(duì) list2 產(chǎn)生任何影響,因?yàn)?list2 和 list1 作為整體是兩個(gè)不同的對(duì)象,并不共享內(nèi)存地址。操作過(guò)后 list2 不變,list1 會(huì)發(fā)生改變。

再來(lái)看,list1[0].append(3) 表示對(duì) list1 中的第一個(gè)列表新增元素 3。因?yàn)?list2 是 list1 的淺拷貝,list2 中的第一個(gè)元素和 list1 中的第一個(gè)元素,共同指向同一個(gè)列表,因此 list2 中的第一個(gè)列表也會(huì)相對(duì)應(yīng)的新增元素 3。

最后是 list1[1] += (50, 60),因?yàn)樵M是不可變的,這里表示對(duì) list1 中的第二個(gè)元組拼接,然后重新創(chuàng)建了一個(gè)新元組作為 list1 中的第二個(gè)元素,而 list2 中沒(méi)有引用新元組,因此 list2 并不受影響。

Python 深拷貝

通過(guò)這個(gè)例子,你可以很清楚地看到使用淺拷貝可能帶來(lái)的副作用。如果想避免這種副作用,完整地拷貝一個(gè)對(duì)象,就需要使用深拷貝。所謂深拷貝,是指重新分配一塊內(nèi)存,創(chuàng)建一個(gè)新的對(duì)象,并且將原對(duì)象中的元素,以遞歸的方式,通過(guò)創(chuàng)建新的子對(duì)象拷貝到新對(duì)象中。因此,新對(duì)象和原對(duì)象沒(méi)有任何關(guān)聯(lián)。

Python 中以 copy.deepcopy() 來(lái)實(shí)現(xiàn)對(duì)象的深度拷貝。比如上述例子寫成下面的形式,就是深度拷貝:

import copy
list1 = [[1, 2], (30, 40)]
list2 = copy.deepcopy(list1)
list1.append(100)
print("list1:",list1)
print("list2:",list2)
list1[0].append(3)
print("list1:",list1)
print("list2:",list2)
list1[1] += (50, 60)
print("list1:",list1)
print("list2:",list2)

運(yùn)行結(jié)果為:

list1: [[1, 2], (30, 40), 100]
list2: [[1, 2], (30, 40)]
list1: [[1, 2, 3], (30, 40), 100]
list2: [[1, 2], (30, 40)]
list1: [[1, 2, 3], (30, 40, 50, 60), 100]
list2: [[1, 2], (30, 40)]

可以看到,無(wú)論 list1 如何變化,list2 都不變。因?yàn)榇藭r(shí)的 list1 和 list2 完全獨(dú)立,沒(méi)有任何聯(lián)系。

不過(guò),深度拷貝也不是完美的,往往也會(huì)帶來(lái)一系列問(wèn)題。如果被拷貝對(duì)象中存在指向自身的引用,那么程序很容易陷入無(wú)限循環(huán),例如:

import copy
list1 = [1]
list1.append(list1)
print(list1)
list2 = copy.deepcopy(list1)
print(list2)

運(yùn)行結(jié)果為:

[1, [...]]
[1, [...]]

此例子中,列表 x 中有指向自身的引用,因此 x 是一個(gè)無(wú)限嵌套的列表。但是當(dāng)深度拷貝 x 到 y 后,程序并沒(méi)有出現(xiàn)棧溢出的現(xiàn)象。這是為什么呢?

其實(shí),這是因?yàn)樯疃瓤截惡瘮?shù) deepcopy 中會(huì)維護(hù)一個(gè)字典,記錄已經(jīng)拷貝的對(duì)象與其 ID??截愡^(guò)程中,如果字典里已經(jīng)存儲(chǔ)了將要拷貝的對(duì)象,則會(huì)從字典直接返回。通過(guò)查看 deepcopy 函數(shù)實(shí)現(xiàn)的源碼就會(huì)明白:

def deepcopy(x, memo=None, _nil=[]):
    """Deep copy operation on arbitrary Python objects.
       
    See the module's __doc__ string for more info.
    """
   
    if memo is None:
        memo = {}
    d = id(x) # 查詢被拷貝對(duì)象 x 的 id
    y = memo.get(d, _nil) # 查詢字典里是否已經(jīng)存儲(chǔ)了該對(duì)象
    if y is not _nil:
        return y # 如果字典里已經(jīng)存儲(chǔ)了將要拷貝的對(duì)象,則直接返回
        ...

看完了這篇文章,相信你對(duì)python深拷貝指的是什么有了一定的了解,想了解更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道,感謝各位的閱讀!

網(wǎng)頁(yè)標(biāo)題:python深拷貝指的是什么-創(chuàng)新互聯(lián)
文章起源:http://jinyejixie.com/article16/cchhdg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃、網(wǎng)站改版、定制網(wǎng)站、App開(kāi)發(fā)微信公眾號(hào)、關(guān)鍵詞優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作
黄浦区| 洪洞县| 聂荣县| 海口市| 景宁| 五台县| 南安市| 四川省| 北海市| 南华县| 松潘县| 韶关市| 上饶县| 太仆寺旗| 古交市| 五台县| 获嘉县| 枣庄市| 漠河县| 木里| 天祝| 广河县| 宜春市| 镶黄旗| 长葛市| 巴林右旗| 巩义市| 双柏县| 仁怀市| 阜宁县| 广丰县| 玉林市| 安阳市| 广宁县| 凌云县| 临泽县| 昆明市| 武定县| 兴安县| 平邑县| 武汉市|