由于元组是不可变的,为什么切片它们会复制而不是视图?

Qua*_*LII 11 python

据我所知,元组和字符串是不可变的,允许优化,例如重新使用不会改变的内存.但是,一个明显的优化,使得元组切片引用与原始元组相同的内存,不包含在python中.

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

def test(n):
    tup = tuple(range(n))
    for i in xrange(n):
        tup[0:i]
Run Code Online (Sandbox Code Playgroud)

如果实现了这种优化,是否会出现一些python行为?即使原始文件是不可变的,复制还有一些性能优势吗?

hpa*_*ulj 3

到了view,你在想什么相当于什么numpy吗?我很熟悉如何以及为什么numpy这样做。

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

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

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

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

制作元组切片视图(在 numpy 意义上)会产生任何意想不到的后果吗?numpy视图和副本之间的区别是用户最难掌握的事情之一。由于元组应该是不可变的(即元组中的指针无法更改),因此实现视图可能对用户不可见。但我仍然想知道。

在版本的一个分支上尝试这个想法可能是最有意义的PyPy- 除非你真的想深入研究Cpython代码。或者作为带有Cython.