一养交、賦值生成引用钦奋,而不是拷貝
首先你需要知道蹬耘,Python中賦值操作總是儲存對象的引用,而不是對象的拷貝躏精。例如:
a = 3
b = [3, a, 3]
請問驮履,當(dāng)運(yùn)行 a = 9 時(shí)
列表 b 是什么樣子鱼辙?
答案:不變
由于引用實(shí)現(xiàn)為指針,b = [3, a, 3] 意思是:列表的第一玫镐、三個(gè)元素是3倒戏,中間的元素指向變量 a 所指向的對象3。因?yàn)閿?shù)字恐似、字符串杜跷、元組是不可變的,所以蹂喻,當(dāng)運(yùn)行到 a = 9 時(shí)葱椭,實(shí)際上是創(chuàng)建對象 9,再將已有的變量 a 指向?qū)ο?9的內(nèi)存空間口四。而對象 3 仍然在原來的內(nèi)存空間上孵运,所以列表第二個(gè)元素也還指向它。
再比如:
a = [1,2,3]
b = [3, a, 3]
請問蔓彩,當(dāng)運(yùn)行a[1] = 99時(shí)治笨,
b是什么樣子?
答案:[3, [1, 99, 3], 3]
我們知道赤嚼,變量 a 引用了列表 [1,2,3]旷赖。同時(shí),變量 b 中的第二個(gè)元素也引用了 [1,2,3]更卒,關(guān)鍵點(diǎn)是:a[1] = 99運(yùn)行后等孵,是在原處改變了列表 [1,2,3],變?yōu)?[1, 99, 3]蹂空,而不是重新創(chuàng)建新列表俯萌,因?yàn)榱斜砼c數(shù)字的區(qū)別之一是,它可以完全的自由改變上枕,而數(shù)字不可變咐熙,也就是說不可在原處改變。
在這里辨萍,列表 b 引用了列表 a所指向的對象棋恼,因此,改變列表 a 指向的對象內(nèi)容時(shí),也改變了列表 b 所指向的內(nèi)容爪飘,這稱為共享引用义起。
如果你不希望有這樣的特性,可以明確地對它們進(jìn)行拷貝师崎,以避免對象的共享并扇。就列表而言,可以通過沒有限制條件的分片抡诞,生成一個(gè)新的拷貝,也就是通過 list[:] 產(chǎn)生一個(gè)新列表:
a = [1,2,3]
b = [3, a[:], 3]
注意土陪,當(dāng)列表分片中昼汗,起始索引和結(jié)束索引都省略的情況下,分片就會(huì)抽取序列中的每一項(xiàng)鬼雀,這樣就生成了一個(gè)頂部拷貝(一個(gè)新的顷窒、無共享的對象)。