Python 既然元组是不可变的,为什么切片它们会生成副本而不是视图?

Python 既然元组是不可变的,为什么切片它们会生成副本而不是视图?,python,Python,据我所知,元组和字符串是不可变的,以允许优化,例如重复使用不会改变的内存。然而,python中没有包含一个明显的优化,即使元组片段引用与原始元组相同的内存 我知道这个优化没有包括在内,因为当我计算以下函数的时间时,所花费的时间是O(n^2)而不是O(n),所以完全复制正在进行: def test(n): tup = tuple(range(n)) for i in xrange(n): tup[0:i] 如果实现了此优化,python的某些行为是否会改变?即使原

据我所知,元组和字符串是不可变的,以允许优化,例如重复使用不会改变的内存。然而,python中没有包含一个明显的优化,即使元组片段引用与原始元组相同的内存

我知道这个优化没有包括在内,因为当我计算以下函数的时间时,所花费的时间是O(n^2)而不是O(n),所以完全复制正在进行:

def test(n):
    tup = tuple(range(n))
    for i in xrange(n):
        tup[0:i]

如果实现了此优化,python的某些行为是否会改变?即使原始文件是不可变的,复制也会带来一些性能上的好处吗?

通过
查看
,您是否想到了与
numpy
相同的功能?我很熟悉numpy是如何以及为什么这样做的

numpy
array
是一个具有形状和数据类型信息的对象,外加一个数据缓冲区。您可以在
\uuu数组\u接口\uu
属性中看到此信息。
视图是一个新的numpy对象,具有自己的shape属性,但具有指向源缓冲区中某个位置的新数据缓冲区指针。它还有一个标志,上面写着“我不拥有缓冲区”
numpy
还维护自己的引用计数,因此如果删除(并垃圾收集)原始(所有者)数组,数据缓冲区不会被破坏

视图的这种使用可以大大节省时间,特别是对于非常大的阵列(关于内存错误的问题很常见)。视图还允许不同的
dtype
,因此可以以4字节整数或1字节字符等格式查看数据缓冲区

这将如何应用于元组?我猜这需要很多额外的行李。元组由一组固定的对象指针组成,可能是一个C数组。视图将使用相同的数组,但有自己的开始和结束标记(指针和/或长度)。共享旗帜怎么样?垃圾收集

元组的典型大小和用途是什么?元组的一个常见用途是将参数传递给函数。我的猜测是,在一个典型的Python运行中,大多数元组都是小的-0、1或2元素。切片是允许的,但它们很常见吗?小元组还是大元组

制作元组切片视图(在numpy意义上)会有任何意外的后果吗?视图和副本之间的区别是
numpy
用户很难掌握的事情之一。由于元组被认为是不可变的(即元组中的指针不能更改),因此实现视图可能对用户不可见。但我还是想知道


PyPy
版本的一个分支上尝试这个想法可能是最有意义的——除非您真的喜欢深入研究
Cpython
代码。或者作为一个自定义类,使用
Cython

有时答案是“因为还没有人花时间完全实现它”。提交一个请求:)正如您所指出的,这可能是减少复制量之间的折衷,减少原始元组的引用计数,以便可以更早地对其进行垃圾收集;如果创建视图具有(相对)较大的固定成本,我不会感到惊讶。相关: