[問題] list與list[:]差異

看板Python作者時間3年前 (2020/08/30 00:40), 編輯推噓3(3012)
留言15則, 3人參與, 3年前最新討論串1/1
以前都沒注意到兩者不太一樣 直到我跑了下面這段碼 def subsets(self, nums): def backtrack(start, end, tmp): ans.append(tmp[:]) for i in range(start, end): tmp.append(nums[i]) backtrack(i+1, end, tmp) tmp.pop() ans = [] backtrack(0, len(nums), []) return ans 假如nums=[1,2,3] 照這段碼跑下去, tmp能夠隨著函數的呼叫持續變動, 最後ans 會返回1,2,3 [[],[1],[1,2],[1,2,3],[1,3],[2],[2,3],[3]] 然而如果第三行的tmp[:]改為tmp 最後只會是[[],[],[],[],[],[],[],[]] 不知道兩者間的差別在哪 而這差別除了在函數呼叫有影響外, 還有什麼時候要注意呢 以往沒特別打上[:]好像都沒出過事@@ 用type看了一下都是<class 'list'> 我猜會不會tmp只是類似這list開頭的指標 而tmp[:]才是整段list的值? -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 12.185.151.146 (美國) ※ 文章網址: https://www.ptt.cc/bbs/Python/M.1598719240.A.3A8.html

08/30 02:11, 3年前 , 1F
是的 tmp只是指標 tmp[:] == tmp.copy()
08/30 02:11, 1F

08/30 22:34, 3年前 , 2F
tmp[:]是淺複製(shallow copy)
08/30 22:34, 2F

08/31 10:07, 3年前 , 3F
沒錯,對變數賦值時其實是將變數指向某段記憶體位址,
08/31 10:07, 3F

08/31 10:07, 3年前 , 4F
例如a=[1,2,3], b=a, c=a的意思是創出一段值為[1,2,3]
08/31 10:07, 4F

08/31 10:07, 3年前 , 5F
的記憶體位置,然後將a指向它,b、c則跟a也一樣指向它
08/31 10:07, 5F

08/31 10:07, 3年前 , 6F
。透過a、b、c任一個變數使用method來修改[1,2,3]時,
08/31 10:07, 6F

08/31 10:07, 3年前 , 7F
指向該處的a,b,c當然也就隨之而變。而賦值為list[:]時
08/31 10:07, 7F

08/31 10:07, 3年前 , 8F
則是建立一個新的記憶體位址,其值為list[:],修改原
08/31 10:07, 8F

08/31 10:07, 3年前 , 9F
本的list當然就不會影響到這新的、獨立的東西。
08/31 10:07, 9F

08/31 10:10, 3年前 , 10F
所以你的程式碼將list[:]改成list後,跑的結果是將ans
08/31 10:10, 10F

08/31 10:10, 3年前 , 11F
一直append上tmp,而這個tmp指向的值則是你最後將tmp
08/31 10:10, 11F

08/31 10:10, 3年前 , 12F
給pop完的空list。
08/31 10:10, 12F

08/31 10:14, 3年前 , 13F
以上是我非本科系自學新手的理解,若有觀念、名詞錯誤
08/31 10:14, 13F

08/31 10:14, 3年前 , 14F
煩請大大不吝糾正,若是我自以為而沒回答的原po的問題
08/31 10:14, 14F

08/31 10:14, 3年前 , 15F
,也先說抱歉@@
08/31 10:14, 15F
文章代碼(AID): #1VIeK8Ee (Python)