Python淺拷貝-深拷貝 解析

淺拷貝

copy.copy()

copy函數(shù)是淺拷貝嘉冒,只對(duì)可變類型的第一層對(duì)象進(jìn)行拷貝弊予,對(duì)拷貝的對(duì)象開辟新的內(nèi)存空間進(jìn)行存儲(chǔ)丐枉,不會(huì)拷貝對(duì)象內(nèi)部的子對(duì)象

特性: 淺拷貝只會(huì)對(duì)可變類型第一層進(jìn)行拷貝溪食;

  • 可變類型:只能作用于列表/字典/集合,而不能拷貝數(shù)字/字符串/元組力九;
  • 第一層:例如一個(gè)列表內(nèi)的嵌套列表無(wú)法拷貝[1,2,[a,b],3]。
如何驗(yàn)證?

通過(guò)id()對(duì)比拷貝前后對(duì)象的內(nèi)存地址塞赂,或直接用is方法判斷拷貝前后對(duì)象內(nèi)存地址是否相同泪勒。

驗(yàn)證示例:
  • 字符串淺拷貝

    import copy
    a = "abc"
    b = copy.copy(a)
    print("a的內(nèi)存地址:",id(a))
    print("b的內(nèi)存地址:",id(b))
    

    輸出:

    a的內(nèi)存地址: 2140603563288 
    b的內(nèi)存地址: 2140603563288
    

    結(jié)論:未拷貝

  • 數(shù)值淺拷貝

    a = 12
    b = copy.copy(a)
    print("a的內(nèi)存地址:",id(a))
    print("b的內(nèi)存地址:",id(b))
    

    輸出:

    a的內(nèi)存地址: 1896907216
    b的內(nèi)存地址: 1896907216
    

    結(jié)論:未拷貝

  • 列表淺拷貝

    a = [1,2,3]
    b = copy.copy(a)
    print("a的內(nèi)存地址:",id(a))
    print("b的內(nèi)存地址:",id(b))
    

    輸出:

    a的內(nèi)存地址: 2140688273224
    b的內(nèi)存地址: 2140681134216
    

    結(jié)論:拷貝成功,創(chuàng)建了新的內(nèi)存地址

  • 列表嵌套情況淺拷貝(特別注意)

    a = [1,2,[3,4]]
    b = copy.copy(a)
    print("a:",a)
    print("a的內(nèi)存地址:",id(a))
    print("b:",b)
    print("b的內(nèi)存地址:",id(b))
    

    輸出:

    a: [1, 2, [3, 4]]
    a的內(nèi)存地址: 2140679959240
    b: [1, 2, [3, 4]]
    b的內(nèi)存地址: 2140679959112
    

    外部地址改變,創(chuàng)建了新的內(nèi)存地址

    驗(yàn)證內(nèi)部嵌套列表是否拷貝:

    In [43]: id(a[2])
    Out[43]: 2140680066952
    
    In [44]: id(b[2])
    Out[44]: 2140680066952
    

    結(jié)論:嵌套列表內(nèi)存地址相同酣藻,未進(jìn)行拷貝

    再次驗(yàn)證曹洽,嘗試修改a列表鳍置,是否對(duì)b列表造成影響:

    In [45]: a.append(5)
    In [46]: a[2].append("a")
    In [48]: b
        
    Out[48]: [1, 2, [3, 4, 'a']]
    

    分析:a列表修改外層列表不影響b列表辽剧;修改a列表的子列表會(huì)同時(shí)改變b列表的子列表。

    結(jié)論

    符合淺拷貝的特性税产,淺拷貝只會(huì)對(duì)可變類型第一層進(jìn)行拷貝怕轿,而不會(huì)拷貝其可變類型的子對(duì)象,因此未拷貝部分指向的仍是同一個(gè)內(nèi)存地址辟拷;

深拷貝

copy.deepcopy

deepcopy函數(shù)是深拷貝, 只要發(fā)現(xiàn)對(duì)象有可變類型就會(huì)對(duì)該對(duì)象到最后一個(gè)可變類型的每一層對(duì)象就行拷貝, 對(duì)每一層拷貝的對(duì)象都會(huì)開辟新的內(nèi)存空間進(jìn)行存儲(chǔ)撞羽。

深拷貝同樣無(wú)法拷貝不可變類型:字符串、數(shù)字衫冻、元組诀紊。

  • 不可變類型的深拷貝(主要討論元組及其子元素)
# 不可變類型元組(需要特別注意)  
In [59]: a = (1,2)

In [60]: b = copy.deepcopy(a)

In [61]: id(a)
Out[61]: 2140688276424

In [62]: id(b)
Out[62]: 2140688276424
      
In [63]: a = (1,2,[1,3])

In [64]: b =copy.deepcopy(a)

    
# 此處雖然外層元組是不可變類型,但內(nèi)存地址依然改變了隅俘,原因是深拷貝會(huì)對(duì)所有可變子對(duì)象進(jìn)行拷貝邻奠,因此內(nèi)部列表會(huì)被拷貝,內(nèi)存地址改變
In [65]: id(a)
Out[65]: 2140685431720

In [66]: id(b)
Out[66]: 2140688106408
    
# 其內(nèi)部的子列表被拷貝为居,內(nèi)存地址改變碌宴,由于元組是不可變類型,內(nèi)部改變蒙畴,其本身地址也會(huì)改變贰镣。
In [67]: id(a[2])
Out[67]: 2140681195272

In [68]: id(b[2])
Out[68]: 2140687283336
# 其內(nèi)部的不可變對(duì)象無(wú)法拷貝,內(nèi)存地址不變
In [69]: id(a[1])
Out[69]: 1896906896

In [70]: id(b[1])
Out[70]: 1896906896
  

? 結(jié)論:

? 不可變類型進(jìn)行深拷貝如果子對(duì)象沒(méi)有可變類型則不會(huì)進(jìn)行拷貝膳凝,而只 是拷貝了這個(gè)對(duì)象的引用碑隆,否則會(huì)對(duì)該對(duì)象到最后一個(gè)可變類型的每一層 對(duì)象就行拷貝, 對(duì)每一層拷貝的對(duì)象都會(huì)開辟新的內(nèi)存空間進(jìn)行存儲(chǔ)

  • 可變類型的深拷貝(主要討論列表及子列表)

    In [77]: a = [1,2,[1,2,3]]
    
    In [78]: b = copy.deepcopy(a)
    # 外部列表內(nèi)存地址改變
    In [79]: id(a)
    Out[79]: 2140687234824
    
    In [80]: id(b)
    Out[80]: 2140681187208
    
    # 子列表內(nèi)存地址也改變
    In [81]: id(a[2])
    Out[81]: 2140681025608
    
    In [82]: id(b[2])
    Out[82]: 2140690147272
        
    # 改變子列表元素不會(huì)再影響deepcoy的子列表元素
    In [83]: a[2].append(3)
    In [84]: a
    Out[84]: [1, 2, [1, 2, 3, 3]]
        
    In [85]: b
    Out[85]: [1, 2, [1, 2, 3]]
    
    

    結(jié)論:

    可變類型進(jìn)行深拷貝會(huì)對(duì)該對(duì)象到最后一個(gè)可變類型的每一層對(duì)象就行拷貝, 對(duì)每一層拷貝的對(duì)象都會(huì)開辟新的內(nèi)存空間進(jìn)行存儲(chǔ)。

總結(jié)

  • 淺拷貝使用copy.copy函數(shù)
  • 深拷貝使用copy.deepcopy函數(shù)
  • 不管是給對(duì)象進(jìn)行深拷貝還是淺拷貝蹬音,只要拷貝成功就會(huì)開辟新的內(nèi)存空間存儲(chǔ)拷貝的對(duì)象上煤。
  • 淺拷貝和深拷貝的區(qū)別是:
    • 淺拷貝最多拷貝對(duì)象的一層,深拷貝可能拷貝對(duì)象的多層祟绊。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末楼入,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子牧抽,更是在濱河造成了極大的恐慌嘉熊,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,865評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扬舒,死亡現(xiàn)場(chǎng)離奇詭異阐肤,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,296評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門孕惜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)愧薛,“玉大人,你說(shuō)我怎么就攤上這事衫画『谅” “怎么了?”我有些...
    開封第一講書人閱讀 169,631評(píng)論 0 364
  • 文/不壞的土叔 我叫張陵削罩,是天一觀的道長(zhǎng)瞄勾。 經(jīng)常有香客問(wèn)我,道長(zhǎng)弥激,這世上最難降的妖魔是什么进陡? 我笑而不...
    開封第一講書人閱讀 60,199評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮微服,結(jié)果婚禮上趾疚,老公的妹妹穿的比我還像新娘。我一直安慰自己以蕴,他們只是感情好糙麦,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,196評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著舒裤,像睡著了一般喳资。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上腾供,一...
    開封第一講書人閱讀 52,793評(píng)論 1 314
  • 那天仆邓,我揣著相機(jī)與錄音,去河邊找鬼伴鳖。 笑死节值,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的榜聂。 我是一名探鬼主播搞疗,決...
    沈念sama閱讀 41,221評(píng)論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼须肆!你這毒婦竟也來(lái)了匿乃?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,174評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤豌汇,失蹤者是張志新(化名)和其女友劉穎幢炸,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拒贱,經(jīng)...
    沈念sama閱讀 46,699評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宛徊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,770評(píng)論 3 343
  • 正文 我和宋清朗相戀三年佛嬉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闸天。...
    茶點(diǎn)故事閱讀 40,918評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡暖呕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出苞氮,到底是詐尸還是另有隱情湾揽,我是刑警寧澤,帶...
    沈念sama閱讀 36,573評(píng)論 5 351
  • 正文 年R本政府宣布葱淳,位于F島的核電站钝腺,受9級(jí)特大地震影響抛姑,放射性物質(zhì)發(fā)生泄漏赞厕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,255評(píng)論 3 336
  • 文/蒙蒙 一定硝、第九天 我趴在偏房一處隱蔽的房頂上張望皿桑。 院中可真熱鬧,春花似錦蔬啡、人聲如沸诲侮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,749評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)沟绪。三九已至,卻和暖如春空猜,著一層夾襖步出監(jiān)牢的瞬間绽慈,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,862評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工辈毯, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留坝疼,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,364評(píng)論 3 379
  • 正文 我出身青樓谆沃,卻偏偏與公主長(zhǎng)得像钝凶,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子唁影,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,926評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,113評(píng)論 1 32
  • 1.設(shè)計(jì)模式是什么据沈? 你知道哪些設(shè)計(jì)模式哟沫,并簡(jiǎn)要敘述?設(shè)計(jì)模式是一種編碼經(jīng)驗(yàn)卓舵,就是用比較成熟的邏輯去處理某一種類型...
    龍飝閱讀 2,165評(píng)論 0 12
  • 一南用、GIL鎖 1.1、GIL面試題:描述Python GIL的概念, 以及它對(duì)python多線程的影響裹虫?編寫一個(gè)多...
    IIronMan閱讀 452評(píng)論 0 0
  • 1. 引用類型有哪些肿嘲?非引用類型有哪些 引用類型:對(duì)象、數(shù)組筑公、函數(shù)雳窟、正則;指的是那些保存在堆內(nèi)存中的對(duì)象匣屡,變量中保...
    曾祥輝閱讀 217評(píng)論 0 0
  • 前世今生封救,一幕幕的在王飛的腦子里閃過(guò),家破人亡捣作,一切的一切究竟拜誰(shuí)所賜誉结。重生后他要讓那些欺負(fù)他的人付出代價(jià)。...
    小孩子吃飯閱讀 109評(píng)論 0 0