作者uranusjr (←這人是超級笨蛋)
看板Python
標題Re: [問題] 關於list一問
時間Mon Mar 12 12:29:36 2012
※ 引述《latefall (驚起卻回頭)》之銘言:
: 最近初學python遇到一個list的問題
: 想求板上大大解答
: 我是用python 2.6.5在ubuntu上跑
: 後來在OS X上用python2跑也有一樣的問題
: 如果我寫
: x=[0,0]
: y=[0,0,0]
: for i in range(3):
: x[1]=i
: y[i]=x
: print y
: 輸出是:
: [[0, 2], [0, 2], [0, 2]]
: 如果把y[i]=x那一行改成(其他保持不變)
: y[i]=[x[n] for n in range(2)]
: 輸出變成:
: [[0, 0], [0, 1], [0, 2]]
: 我以為這兩個寫法是等價的?
: 是我有誤解還是這是bug呢?
: 感謝解答
第一種的流程:
步驟 x 值 y 值
===================================================
把 x[1] 設成 0 [0, 0] [0, 0, 0]
把 y[0] 設成 x [0, 0] [[0, 0], 0, 0]
把 x[1] 設成 1 [0, 1] [[0, 1], 0, 0]
把 y[1] 設成 x [0, 1] [[0, 1], [0, 1], 0]
把 x[1] 設成 2 [0, 2] [[0, 2], [0, 2], 0]
把 y[2] 設成 x [0, 2] [[0, 2], [0, 2], [0, 2]]
關鍵在於 Python 的變數和 C(和其它類似語言)中變數的概念並不一樣
在 Python 中, 所有的變數都是參考, 而不是容器
所以例如 y = x 這種述句的作用是「把 y 指向 x 的內容」
當你改變 x 的內容時, y 的內容(也就是 x 的內容)會一起改變
因為 x 和 y 是指向同一個東西, 而非同樣值的兩個獨立物件
至於第二種, 因為 list comprehension 的結果是生成一個新物件
所以在這個作法中 y[0] y[1] 和 y[2] 都分別指向不同的物件
與第一種作法並不等價
--
「我最想要的同伴嘛,首先是要笑口常開,其次是我們能永遠不會發生誤會。
如果這些都能辦到的話,嗯,如果他是世界上第一流的橋手,也還不錯。」
-- 班尼多‧加羅素,前義大利藍隊成員
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 114.32.81.146
推 latefall:感謝! 03/12 17:16
推 latefall:所以 我應該把python變數都當成c的指標來理解? 03/12 17:20
推 latefall:好像只有list是指標 感謝! 03/12 17:39
推 AstralBrain:所有變數都是指標 03/13 03:09
推 darkgerm:第二個方法是做了深複製,才有你希望的結果 03/13 21:38
推 latefall:感謝樓上幾位 03/13 22:30
推 mikapauli:所有變數都是指標,但是物件有可不可變的差別 03/14 02:29
→ mikapauli:因此只有可變物件(如list)才有辦法像C的指標那樣使用 03/14 02:31
推 mikapauli:不可變物件無法改變其值,只能靠"指標"的改變 03/14 02:41
→ mikapauli:另外在Python中immutable<==>hashable,自定義物件例外 03/14 02:44