python - 与列表切片相反,元组切片不返回新对象

标签 python list tuples slice cpython

在 Python(2 和 3)中。每当我们使用列表切片时,它都会返回一个新对象,例如:

l1 = [1,2,3,4]
print(id(l1))
l2 = l1[:]
print(id(l2))

输出
>>> 140344378384464
>>> 140344378387272

如果用元组重复相同的事情,则返回相同的对象,例如:
t1 = (1,2,3,4)
t2 = t1[:]
print(id(t1))
print(id(t2))

输出
>>> 140344379214896
>>> 140344379214896

如果有人能阐明为什么会发生这种情况,那就太好了,在我的 Python 经验中,我一直认为空切片返回一个新对象。

我的理解是它返回相同的对象,因为元组是不可变的,并且没有必要创建它的新副本。但同样,在任何地方的文件中都没有提到它。

最佳答案

实现可以自由地为 返回相同的实例不可变类型 (在 CPython 中,您有时可能会看到类似的字符串和整数优化)。由于对象无法更改,因此用户代码中没有任何内容需要关心它是否持有唯一实例或只是对现有实例的另一个引用。

您可以在 C 代码中找到短路here .

static PyObject*
tuplesubscript(PyTupleObject* self, PyObject* item)
{
    ... /* note: irrelevant parts snipped out */
    if (start == 0 && step == 1 &&
                 slicelength == PyTuple_GET_SIZE(self) &&
                 PyTuple_CheckExact(self)) {
            Py_INCREF(self);          /* <--- increase reference count */
            return (PyObject *)self;  /* <--- return another pointer to same */
        }
    ...

这是一个实现细节,注意 pypy不这样做。

关于python - 与列表切片相反,元组切片不返回新对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58507216/

相关文章:

在 Windows 10 上安装 python 3.5 Scipy 包

列表到元组计数值重复和元组内的列表 - Haskell

python - zip 基于 python 中的真/假元组

python - 通过组合元组元素获取元组列表的产品?

python - 为什么我的 Deep Q Net 和 Double Deep Q Net 不稳定?

python - 如何使用 numpy 对循环数组进行切片

python - 装饰生成器

python - 设置元素的同一列表的所有元素之间的交集

java - 合并列表中的多个 JObject - Json4s

list - SwiftUI 如何在 EditMode 更改时执行操作?