gpt4 book ai didi

python - 由于元组是不可变的,为什么切片它们会生成副本而不是 View ?

转载 作者:太空狗 更新时间:2023-10-29 19:28:36 25 4
gpt4 key购买 nike

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

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

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

如果实现此优化,python 的某些行为是否会发生变化?即使原始文件不可变,复制是否也有一些性能优势?

最佳答案

通过 view,您是否正在考虑与 numpy 所做的等效的事情?我很熟悉 numpy 是如何以及为什么这样做的。

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

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

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

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

制作元组切片 View (在 numpy 意义上)会不会有任何意想不到的后果? View 和副本之间的区别是 numpy 用户最难掌握的事情之一。由于元组应该是不可变的 - 即元组中的指针不能更改 - 实现 View 可能对用户不可见。但我还是想知道。

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

关于python - 由于元组是不可变的,为什么切片它们会生成副本而不是 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34710510/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com