在 python 中,如果 x 是 list,為什麼 x += "ha" 可以執行,而 x = x + "ha" 卻丟擲異常呢
問題
眾所周知,在 python 中,+ 運算子可以使用在列表上,+ 運算子只需要第二個運算元是可迭代的(原文:iterable。@justjavac),那麼 + 顯然可以運算在 "ha" 上。
程式碼如下:
>>> x = []
>>> x += "ha"
>>> x
['h', 'a']
>>> x = x + "ha"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "str") to list
解答
當我們在列表 list 上使用 += 的時候,其實相當於呼叫函式 extend(),而不是使用的 +。
- 你可以在一個可迭代(iterable)物件上呼叫 extend()。
- 但是,當您使用 + 時,另一個運算元必須是列表(list)。
為什麼 python 會如此詭異,也許是出於效能方面的考慮。 呼叫 + 時,將會建立一個新的物件,並複製裡面的所有內容。但是當呼叫 extend() 函式時,將可以使用現有的空間。
這樣就會產生另一個副作用:如果你寫 X += Y,在其他對列表的引用(reference)中,會看到變化;但如果你使用 X = X + Y,就不會。
下面的程式碼說明了這一點:
>>> x = ['a','b']
>>> y = ['c', d']
>>> z = x
>>> x += y
>>> z
['a', 'b', 'c', 'd'] // z 也發生了變化
>>> x = ['a','b']
>>> y = ['c', d']
>>> z = x
>>> x = x + y
>>> z
['a', 'b'] // z 函式原始值
參考文獻
python:+= 的原始碼:
static PyObject *
list_inplace_concat(PyListObject *self, PyObject *other)
{
PyObject *result;
result = listextend(self, other);
if (result == NULL)
return result;
Py_DECREF(result);
Py_INCREF(self);
return (PyObject *)self;
}
python:+ 的原始碼:
static PyObject *
list_concat(PyListObject *a, PyObject *bb)
{
Py_ssize_t size;
Py_ssize_t i;
PyObject **src, **dest;
PyListObject *np;
if (!PyList_Check(bb)) {
PyErr_Format(PyExc_TypeError,
"can only concatenate list (not \"%.200s\") to list",
bb->ob_type->tp_name);
return NULL;
}
// etc ...
原文:python - If x is list, why does x += "ha" work, while x = x + "ha" throw an exception?
譯文:在 python 中,如果 x 是 list,為什麼 x += "ha" 可以執行,而 x = x + "ha" 卻丟擲異常呢?
譯者:justjavac
相關文章
- 面試官:x !== x 可以為 true ?面試
- hadoop之 Hadoop 2.x HA 、FederationHadoop
- IOS基礎-設計UI@1X@2X@3X是什麼iOSUI
- C++中x&(x-1)是什麼意思(京東筆試)C++筆試
- 什麼是10x工程師(10x engineers)?工程師
- 由rotation轉為w,x,y,z為nan,為什麼呢NaN
- X86中斷/異常與APICAPI
- HTTP X-Forwarded-For是什麼?HTTPForward
- 什麼是V、W、X模型?模型
- Window X86和X64的區別 Window x64和Window x86是什麼意思
- python3.x的異常處理Python
- 為什麼'\x1B'.length===1?\x與\u知識延伸
- laravel7.x 該怎麼自己捕獲ModelNotFoundException 這種異常呢?LaravelException
- Java RMI遇到的Connection refused to Host: 127.x.x.x/192.x.x.x/10.x.x.x問題解決方法Java
- Swift 中 throws 異常丟擲Swift
- 【ha知識兩問】ha軟體是什麼?ha軟體用途有哪些?
- Kent Beck的3X模型是什麼?模型
- 什麼是 10x 程式設計師程式設計師
- x86 版和x64版有什麼區別?
- vivo X20和X20 Plus對比評測 vivo X20和X20Plus有什麼區別?
- Oracle X$ View:X$KJBLOracleView
- C++程式丟擲異常後執行順序C++
- unserialize() 實戰之 vBulletin 5.x.x 遠端程式碼執行
- HA執行流程
- Heartbeat3.x應用全攻略之: 測試Heartbeat的HA功能薦
- 檔案許可權中 chmod、u+x、u、r、w、x分別代表什麼
- Gradle在cocos2d-x(2.x)遊戲中整合Gradle遊戲
- Python中x=y與x==y的區別。(比較簡單)Python
- python2.x和python3.x區別Python
- vivo x9和X9s Plus區別對比 vivo X9s和X9sPlus有什麼區別?
- java中異常丟擲後程式碼還會繼續執行嗎Java
- iPhone X和Find X對比評測 OPPO Find X和iPhone X哪個好?iPhone
- Python3.x和Python2.x的區別Python
- X明X源面試題《三》面試題
- junit4.x and 3.x
- x$le及x$bh詳解
- 編譯原理: FIRST(x) FOLLOW(x) SELECT(x)的計算編譯原理
- Visual Studio Code為什麼能這麼牛X?