python - 如果 x 是列表,为什么 x += "ha"工作,而 x = x + "ha"抛出异常?

标签 python list operators

据我所知,列表的 + op 只要求第二个操作数是可迭代的,“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

最佳答案

在列表中使用 += 就像调用 extend,而不是 +

  • 您可以使用可迭代对象调用 extend
  • 您只能将 + 与另一个列表一起使用。

我只能猜测为什么会做出这个决定,但我想这是出于性能原因。调用 + 会创建一个新对象并复制所有项目,而 extend 可以在某些情况下使用现有列表对象中的可用空间来保存副本。

这个决定的另一个副作用是,如果你写 x += y 其他对列表的引用会看到变化,但如果你使用 x = x + y 那么他们就不会了。如下所示:

>>> x = ['a','b']
>>> y = ['c', d']
>>> z = x
>>> x += y
>>> z
['a', 'b', 'c', 'd']

>>> x = ['a','b']
>>> y = ['c', d']
>>> z = x
>>> x = x + y
>>> z
['a', 'b']

引用文献

Python source code for list .

+=的源代码:

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;
}

+的源代码:

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 - 如果 x 是列表,为什么 x += "ha"工作,而 x = x + "ha"抛出异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3216706/

相关文章:

python - 您可以根据特征值在另一个数据框中出现的次数来复制 Pandas 数据框中的行吗?

python - 使用装饰器动态地向类添加方法

python - 从列表中分配重复值的列

C++ 列表迭代器在遍历时永远不会到达 end()

php - .= 运算符在 PHP 中是什么意思?

python - 如何使用 numpy 在列表中的值对之间进行插值

Python:拆分列表的元素

java - 标准 API 中是否有任何方法可以反转 retainAll()?

JavaScript 函数表达式前面的加号

Ruby 比较运算符? == 与 ===