2014-01-12 28 views
3

由於一切都在蟒蛇是參考,我不明白髮生了什麼事在下面的代碼:瞭解Python的引用

a = ['one']*3  // a = ['one', 'one', 'one'] 
b = [a]*3   // b = [['one', 'one', 'one'], ['one', 'one', 'one'], ['one', 'one', 'one']] 
b[1][2] = 'two' 

而現在,b爲

[['one', 'one', 'two'], ['one', 'one', 'two'], ['one', 'one', 'two']] 

因爲我們做了b指3乘以a所提及的同一對象,重新分配任何一個組件,則在三個地方看到變化。

但是,當

a = [['one']]*3  // a = [['one'], ['one'], ['one']] 
a[1] = ['two']   

不作a = ['two', 'two', 'two'],只是[['one'], ['two'], ['one']彷彿現在已經指出,三個不同的對象,那麼爲什麼會發生同樣的事情。

我在這裏丟失了一些邏輯嗎?

由於提前, 尼基爾

+0

不是重複,但[此問題](http://stackoverflow.com/questions/20699736/why-should-i-refer-to-names-and-binding-in-python-instead-of-variables和/ 20700226#20700226)與您的相關,並可能有助於瞭解幕後發生的事情。 – aquavitae

回答

3

你沒有改變a[1]的內容,你重新綁定它指向一個單獨的數組。這對a[0]a[2]沒有影響。

嘗試以下操作來代替:

In [4]: a = [['one']]*3 

In [5]: a[1][0] = 'two' 

In [6]: a 
Out[6]: [['two'], ['two'], ['two']] 
+0

似乎是一個可以接受的答案:)...但有點混亂:在前面的例子中,a是1d數組,而b是2d數。那麼爲什麼我們需要'a [1] [0]'來明確地引用對象的第一個元素?......看起來好像'a'和'a [1]'是兩個不同的引用:( –

+0

@NikhilJJoshi:我不確定我是否按照你的最後一句話說,'a','a [1]'和'a [1] [0]'確實是三個不同的參考文獻 – NPE

+0

我試圖理解'和'b'不同,顯然'b [0] [1],b [1] [1]'和'b [2] [1]'指的是同一個對象,那麼爲什麼不在'a [0]','a [1]'和'a [2]'....也許我會更加深入地理解。 –

1

也許我已經找到了理解引用是如何工作就是通過模擬器在Python Tutor運行它們(點擊該鏈接將運行上面有例子)的最佳方式。這使情況非常清楚。這也值得閱讀this article

1

要記住的一個關鍵是對象具有獨立於指向它們的名稱的存在和身份;和x = y確實是而不是的意思是「將x指向的對象的值更改爲y所指向的對象的值」。這意味着「使x指向y指向的內容」。

使用id可能有助於澄清這是怎麼回事:

>>> a = [['one']]*3 
>>> (id(a[0]), id(a[1]), id(a[2])) 
(140193404836320, 140193404836320, 140193404836320) 
>>> a[1] = ['two'] 
>>> (id(a[0]), id(a[1]), id(a[2])) 
(140193404836320, 140193368088088, 140193404836320) 

最初,a[0]a[1]a[2]都是相同的對象,正如人們所預料:

 
     +------+------+------+ 
    a -->|  |  |  | 
     +------+------+------+ 
      \ | /
      | |  | 
      v v  v 
      +---------+ 
      | ['one'] | 
      +---------+ 

然後a[1] = ['two']使a[1]指向一個新對象:

 
     +------+------+------+ 
    a -->|  |  |  | 
     +------+------+------+ 
     |  |  | 
     |  |  | 
     |  |  | 
     |  v  | 
     | +---------+ | 
     | | ['two'] | | 
     | +---------+ | 
     |    | 
     | +---------+ | 
     \> | ['one'] |</ 
      +---------+ 

請注意,該圖被簡化以顯示要點,['one']['two']不是簡單的值,因爲它們出現在圖中。