在元组/列表之间进行转换时会发生什么?

use*_*259 2 python tuples list python-3.x python-internals

在将元组转换为列表或其他方式时,python如何在内部进行转换.

它是否"切换一个标志"(现在你是不可变的,现在你不是!)还是它会遍历这些项并转换它们?

Mar*_*ers 7

元组和列表是完全独立的类型; 因此,在将列表转换为元组或反之亦然时,将创建一个对象并复制元素引用.

Python 确实通过进入另一个对象的内部结构来优化它; 例如,与函数list(tupleobj)基本相同list().extend(tupleobj),然后listextend函数使用Python C API函数简单地复制元组的C数组中的引用:

if (PyList_CheckExact(b) || PyTuple_CheckExact(b) || (PyObject *)self == b) {
    PyObject **src, **dest;
    b = PySequence_Fast(b, "argument must be iterable");
    if (!b)
        return NULL;
    n = PySequence_Fast_GET_SIZE(b);
    if (n == 0) {
        /* short circuit when b is empty */
        Py_DECREF(b);
        Py_RETURN_NONE;
    }
    m = Py_SIZE(self);
    if (list_resize(self, m + n) == -1) {
        Py_DECREF(b);
        return NULL;
    }
    /* note that we may still have self == b here for the
     * situation a.extend(a), but the following code works
     * in that case too.  Just make sure to resize self
     * before calling PySequence_Fast_ITEMS.
     */
    /* populate the end of self with b's items */
    src = PySequence_Fast_ITEMS(b);
    dest = self->ob_item + m;
    for (i = 0; i < n; i++) {
        PyObject *o = src[i];
        Py_INCREF(o);
        dest[i] = o;
    }
    Py_DECREF(b);
    Py_RETURN_NONE;
}
Run Code Online (Sandbox Code Playgroud)

PySequence_Fast_ITEMS是一个宏,用于访问ob_item元组的C结构中的数组,并且for循环将该数组中的项直接复制到self->ob_item数组(从offset开始m).