2012-03-20 31 views
7

***編輯:我原來的例子是粗心的。當我將列表A添加到自身時,行爲不會發生,而是當我添加包含列表A到A本身的列表時。請參閱下面的更正示例。省略號列出並在Python中連接列表本身


我想了解省略號列表(那些出現[...]當你有一個列表的引用本身發生名單)如何工作在Python(2)。

我特別想知道爲什麼,如果A是一個列表,A = A + A似乎以不同的方式工作,以A += A(和A.append(A)

也就是說,你爲什麼得到:

>>> a = [1, 2] 
>>> a = a + [a] 
>>> a 
[1, 2, [1, 2]] 

VS 。

>>> a = [1, 2] 
>>> a += [a] 
>>> a 
[1, 2, [...]] 

(請注意,a.append(一)似乎爲我的工作只是因爲後者沒有。)

有關此省略號列表現象的任何其他更一般信息,如果有助於澄清事情,也將非常感激。

謝謝。

+0

http://stackoverflow.com/questions/2347265/what-does-plus-equals-do-in-python – Dogbert 2012-03-20 08:07:27

+1

'a = [1,2]; a + = a'會使'[1,2,1,2]',而不是'[1,2,[1,2]]。看到重複的問題。 – khachik 2012-03-20 08:20:42

+1

所謂的重複不會討論省略號列表* *。 – Marcin 2012-03-20 08:40:53

回答

6

編輯:(以解決您的編輯提出的問題的其他問題):

a = a + ba += b是不一樣的操作。前者執行a.__add__(b),後者執行a.__iadd__(b)(「就地添加」)。

兩者之間的區別在於前者總是創建一個新對象(並將名稱a重新命名爲該新對象),而後者則在原地修改該對象(如果可以,並且使用列表,它可以)。

爲了說明這一點,只要看看你的對象的地址:

>>> a = [1, 2] 
>>> id(a) 
34660104 
>>> a = a + [a] 
>>> id(a) 
34657224 
>>> id(a[2]) 
34660104 

「新」 a是從頭開始構建,首先從舊列表a取值,然後連接參考舊的對象。

與此相反的:

>>> a = [1, 2] 
>>> id(a) 
34658632 
>>> a += [a] 
>>> id(a) 
34658632 
>>> id(a[2]) 
34658632 

(老答案,解釋循環引用):所以

>>> a = [1, 2]; a += a 
>>> a 
[1, 2, 1, 2] 
>>> a = [1, 2]; a.extend(a) 
>>> a 
[1, 2, 1, 2] 
>>> a = [1, 2]; a += [a] 
>>> a 
[1, 2, [...]] 
>>> a = [1, 2]; a.append(a) 
>>> a 
[1, 2, [...]] 

,總結第一部分:

考慮這個

對於列表,a += a相當於調用​​,它在原地修改a,在此操作開始時添加在a中找到的元素的副本。

相反地,a += [a]對應於a.append(a),這兩者的創建到列表a的引用(即,一個指針到它的存儲器中的地址),並添加到列表中。它構成了所謂的「循環參考」。

如果你要看看a在該點的內部表示,這將是這個樣子:

a: Reference to a list object at address 0xDEADBEEF 
a[0]: Reference to the integer object "1" 
a[1]: Reference to the integer object "2" 
a[2]: Reference to the same list object at address 0xDEADBEEF 

老版本的Python(預1.5.1)還不夠聰明,檢測,所以如果你要做一個print a,你會得到[1, 2, [1, 2, [1, 2, [1, 2, [1, 2, [1, 2, ...等無限循環。從Python 1.5.1開始,解釋器檢測到這一點,而是打印[1, 2, [...]]

0

考慮以下幾點:

In [179]: a = [1, 2] 

In [180]: a+=a 

In [181]: a 
Out[181]: [1, 2, 1, 2] 

In [182]: a.append(a) 

In [183]: a 
Out[183]: [1, 2, 1, 2, [...]] 

In [184]: a[5] 
----------------------------------------------- 
IndexError        Trace 
C:\Users\Marcin\Documents\oneclickcos\oneclickc 
----> 1 a[5] 

IndexError: list index out of range 

In [185]: a[4] 
Out[185]: [1, 2, 1, 2, [...]] 

In [186]: a[3] 
Out[186]: 2 

In [187]: a[4] 
Out[187]: [1, 2, 1, 2, [...]] 

In [188]: a 
Out[188]: [1, 2, 1, 2, [...]] 

In [189]: a[4][3] 
Out[189]: 2 

In [190]: a[4][4] 
Out[190]: [1, 2, 1, 2, [...]] 

In [191]: a[4][5] 
----------------------------------------------- 
IndexError        Trace 
C:\Users\Marcin\Documents\oneclickcos\oneclickc 
----> 1 a[4][5] 

IndexError: list index out of range 

In [192]: a[4][4] 
Out[192]: [1, 2, 1, 2, [...]] 

In [193]: a = [1, 2] 

In [194]: a+=a 

In [195]: a 
Out[195]: [1, 2, 1, 2] 

In [196]: a 
Out[196]: [1, 2, 1, 2] 

In [197]: a 
Out[197]: [1, 2, 1, 2] 

In [198]: a.append(a) 

In [200]: a 
Out[200]: [1, 2, 1, 2, [...]] 

In [201]: a.append(a) 

In [202]: a 
Out[202]: [1, 2, 1, 2, [...], [...]] 

In [203]: a[4] 
Out[203]: [1, 2, 1, 2, [...], [...]] 

In [204]: a[5] 
Out[204]: [1, 2, 1, 2, [...], [...]] 

In [205]: id(a) 
Out[205]: 64692680L 

In [206]: id(a[5]) 
Out[206]: 64692680L 

In [207]: id(a[4]) 
Out[207]: 64692680L 

In [208]: id(a) == id(a[4]) and id(a[4]) == id(a[5]) 
Out[208]: True 

首先注意的所有+=不會創建一個省略號列表。

其次,可以看出,省略號-列表指示accesing該時隙將返回完全相同的列表 - 省略號-列表表示的指針外列表(或,幾乎肯定一個外列表如果有多層嵌套)。