在Python(2.7)中發現了一個前所未有的有趣的事情。擴展奇怪行爲的列表
此:
a = []
a += "a"
不工作,結果是:
>>> a
>>> ["a"]
但
a = []
a = a + "a"
給
>>> TypeError: can only concatenate list (not "str") to list
有人可以解釋爲什麼嗎?感謝您的回答。
在Python(2.7)中發現了一個前所未有的有趣的事情。擴展奇怪行爲的列表
此:
a = []
a += "a"
不工作,結果是:
>>> a
>>> ["a"]
但
a = []
a = a + "a"
給
>>> TypeError: can only concatenate list (not "str") to list
有人可以解釋爲什麼嗎?感謝您的回答。
Python區分+
和+=
運算符,併爲這些運算符提供單獨的鉤子; __add__
和__iadd__
。 list()
類型僅爲後者提供了不同的實現。
列表分別實現這些效率更高; __add__
必須返回一個全新的列表,而__iadd__
只能延伸self
,然後返回self
。
在C代碼中,__iadd__
由list_inplace_concat()
實現,該代碼簡單地稱爲listextend()
,或者在Python代碼中爲[].extend()
。後者通過設計需要任何序列。
另一方面,__add__
方法,由C代表list_concat
,只需要一個list
作爲輸入,可能出於效率的原因;它可以直接在內部C數組上循環並將項目複製到新列表中。
總之,原因__iadd__
接受任何序列是因爲當執行PEP 203(增強添加提案)時,對於列表,最簡單的方法是重用.extend()
方法。
謝謝,Martijn,這是我正在尋找的答案。 – alexvassel
如果a
是一個列表,a + x
只有工作,如果x
也是名單,而a += x
適用於任何可迭代x
。
下可能有助於理解:
In [4]: a = []
In [5]: a += "abc"
In [6]: a
Out[6]: ['a', 'b', 'c']
的關鍵是,"a"
和是可迭代的,這是什麼讓他們對+=
右手邊使用。
這對+
不起作用,因爲後者要求兩個操作數的類型相同(請參閱manual)。
編寫使用+
同樣的事情,你必須展開迭代:
In [7]: a = []
In [8]: a = a + list("abc")
In [9]: a
Out[9]: ['a', 'b', 'c']
換句話說,+=
當應用於列表是更普遍比+
。
問題是關於'lst + = iterable'和'lst + iterable'之間的*差*。 –
它沒有解釋爲什麼你不能連接列表和迭代。 –
@MartijnPieters:好的。查看最新的答案。 – NPE
'+'和'+ ='是不同的操作,即使它們在許多情況下似乎都是一樣的。 –
'+ ='在Python列表(inplace add)中的行爲類似於extend(),另一個稱爲二進制添加。 –