python - 什么时候 array.array 比列表更有效?

标签 python arrays list

我正在看书'Fluent Python ' 当我遇到一个句子,作者说

If you need to store 10 million floating-point values an array is much more efficient, because an array does not actually hold full fledged objects, but only the packed bytes representing their machine values - just like array in C language.

我无法理解作者试图表达的意思。他在说什么“打包字节”? “打包字节存储”是什么意思? . python 列表如何存储它?如果这是使它高效的原因,为什么不以这种方式存储它?

最佳答案

假设您正在处理 8 字节的 float 。在这种情况下,“打包字节”意味着有一个专用的分配内存块,其中前 8 个字节代表第一个 float ,然后接下来的 8 个字节代表下一个 float ,依此类推,没有浪费。这是存储数据的最节省空间的方式(至少,没有压缩)。对于某些操作(例如,数组算术运算),它也可能是最省时的。

Python list 不会以这种方式存储内容。一方面,一个列表元素可能是一个 float ,但下一个可能是其他类型的对象。另一方面,您可以删除、插入或替换列表中的项目。其中一些操作涉及动态地延长或缩短列表。如果项目存储为打包字节,所有这些都非常节省时间和内存。 Python list 类被设计为尽可能通用,在各种类型的操作的效率之间做出折衷。

可能最重要的区别是 Python list,在其底层实现中,是一个充满指向对象的指针的容器,而不是一个充满原始对象的容器内容。其含义之一是对相同 Python 对象的多个引用可以出现在列表 中。另一个是可以非常有效地更改特定项目。例如,假设列表中的第一项 a[0] 是一个整数,但您希望将其替换为占用更多内存的字符串,例如a[0] = "There's a horse in the aisle five." 打包数组必须 (a) 腾出额外空间,移动内存中所有剩余的数组内容,以及 (b) 单独更新某种项目大小和类型的索引。与大多数语言一样,Python 的打包数组实现 (array.array) 甚至不允许这样做:相反,数组保证和强制执行统一的元素大小和类型更有意义。相比之下,在这种情况下,Python list 只需要用另一个指针值覆盖一个指针值,而没有这样的限制。

事实上,现在应该清楚这些指针本身甚至不直接指向对象内容。例如,它们不会直接指向包含浮点值的 8 个字节,而是指向携带所有必要元信息的 PyObj 结构(例如声明“我的内容必须是解释为 float ”)以及内容本身。

在 CPython 实现中,指针本身可能仍(或多或少)打包在内存中。这意味着将一个新项目插入到 list 中通常仍然是低效的(相对于 Python list 实现使用链接列表时的方式)引擎盖下的结构)。

一般来说,没有绝对的“高效”或“低效”之分——这都是关于您使用哪种资源、什么内容类型(以及内容类型的限制)在容器中,您打算如何转换容器或其内容。

关于python - 什么时候 array.array 比列表更有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41307460/

相关文章:

python - 查找一个二维数组中两列元素在另一个二维数组中的对应关系

c++ - 在 std::list 和 std::vector 之间进行选择

r - 将 ifelse() 创建的变量添加到数据框列表

python - 如何更改算法中的参数以获得更好的性能?

python - 创建列表后关闭文件 > text = open ("path/file.ext").read().split()

python - 在python中异步读取和处理图像

Python:循环后为存储在变量中的每个单词评分

python - Apache Solr 6.6 替换文档而不是更新

python - 彩条/绘图问题? "posx and posy should be finite values"

java - 数组和输出