「訳」pythonでは、xがlistの場合、x+=「ha」が実行できるのはなぜですか.

2186 ワード

译文: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
に質問
周知のように、pythonでは、+演算子をリストに使用することができ、+演算子は2番目のオペランドが反復可能である(原文: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

に答える
リストリストで+=を使用する場合、実際には+ではなく関数extend()を呼び出すことに相当します.
  • 反復可能なオブジェクトで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 source code for list.
    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 ...