2011-11-30 117 views
7
>>> b = [] 
>>> c = '1234' 
>>> b += c 
>>> b 
['1', '2', '3', '4'] 
>>> 

這裏發生了什麼?這不應該工作,對吧?還是我錯過了明顯的東西?將一個字符串添加到列表中

>>> b = [] 
>>> c = '1234' 
>>> b + c 
Traceback (most recent call last): 
    File "<pyshell#7>", line 1, in <module> 
    b + c 
TypeError: can only concatenate list (not "str") to list 
>>> 

然後a += b並不總是等同於a = a + b

+1

做的是這種行爲仍然存在在Python 3.x的?我總是發現標準庫類型打破了總體契約,即不影響對原始「a」值的任何其他引用的情況下,a + = b' <=>'a = a + b'。 –

+2

@Karl Knechtel:不幸的是,它仍然存在於Python 3.2.1中。 –

+0

我在Python 3.2中檢查它,是的。我發現這個問題看着一個產生錯誤結果的初學者代碼。我無法在「Learning Python」中找到對此特定行爲的任何引用。我檢查了PEP203,它說'__iadd__'被使用,但他們也說'__iadd__'是就地'__add__',在這種情況下情況並非如此......也許有人可以解釋這種行爲或點/鏈接下的理性對此進行一些討論?我從卡爾的評論中明白,有人關注它 – joaquin

回答

2

字符串是一系列字符。列表操作+=採用任何序列並將每個序列的元素附加到列表中。

(其實+=接受任何可迭代)

+0

b = b + c失敗 – joaquin

+2

'+'與'+ ='不同。 –

+0

我知道,它被稱爲增廣assigment,它被定義爲等同於a = a + b(參見PEP203)。採取這個定義嚴格地促使我錯誤的期望。這讓我很吃驚(可能我從來不敢在Python代碼中爲字符串添加一個列表,所以我從來沒有碰到過這個)。不應該「面對模棱兩可的態度,拒絕猜測的誘惑」。 – joaquin

11

字符串是可迭代:元素是字符串的字符。當您將迭代添加到列表中時,迭代器的元素會附加到列表中。

下列任一會做你期待什麼(即追加字符串,而不是延長以字符串的字符表):

b += [c] 

b.append(c) 
+0

+1使用正確的詞彙表:'iterable' – gecco

9

+=操作擴展名爲的列表而不是附加到:

>>> b = [] 
>>> c = "1234" 
>>> b.append(c) 
>>> b 
['1234'] 
>>> b.extend(c) 
>>> b 
['1234', '1', '2', '3', '4'] 
>>> b += c 
>>> b 
['1234', '1', '2', '3', '4', '1', '2', '3', '4'] 
>>> b += [c] 
>>> b 
['1234', '1', '2', '3', '4', '1', '2', '3', '4', '1234'] 
+0

你知道這些操作符('+','+ =')對iterables/sequences/...的作用嗎? – moooeeeep

0

你期望什麼?如果你想添加ç作爲字符串必須做到:

b.append(c) 

乾杯!

+0

我預計它會失敗 – joaquin

+0

但是,正如蒂姆在上面解釋的那樣,+ =的行爲與請求+ – ocell

+0

不一樣,請參閱Tim帖子的評論。 – joaquin

0

本質上,列表上的+ =運算符將檢索c的迭代器,這將按順序產生單個字符。如果打算將實際字符串添加到列表中,則可以使用b.append('1234')來代替結果['1234']。

2

+ =是用於擴展的語法糖,但+只是列表級聯。如果你擴展,你會迭代參數,在這種情況下是一個字符串。但是你不能將一個字符串連接到一個列表,因此+失敗。

3

這是對原始問題(我認爲已經得到充分回答)的一個答案,但是對於增補作業(+=和類似操作)的語義評論中提出的許多問題。

簡而言之:增量賦值對可變類型的作用與對不可變類型的作用不同。

str,tuple,以及其中的數字類型是不可變的。一旦已創建了一個元組的內容不能改變,所以你得到此行爲:

>>> a = (1, 2) 
>>> b = a 
>>> a += (3, 4) 
>>> a 
(1, 2, 3, 4) 
>>> b 
(1, 2) 

str具有相同的語義。基本上,a += b相當於a = a + b如果a是不可變的。

大多數其他類型,包括list,都是可變的。一個列表的內容可以在適當的位置進行更改,而增強的分配完全就是這樣。因此:

>>> a = [1, 2] 
>>> b = a 
>>> a += [3, 4] 
>>> a 
[1, 2, 3, 4] 
>>> b 
[1, 2, 3, 4] 

而如果第三行用a = a + [3, 4]更換,將創建一個新的列表,並b[1, 2]

對於用戶定義的類,語義依賴於它是如何實現的,但這是它是如何假定每PEP 203

+0

這是一個非常好的觀察。 'a'和'b'共用相同的存儲器地址,直到在賦值運算符的左邊評估'a'?你能包括嗎? – Droogans

相關問題