什么时候数组.array比列表更有效吗?

2024-05-21 11:47:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在读这本书'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列表如何存储它?为什么它不以这种方式存储它,如果这是使它高效的原因?在


Tags: tostoreyouanif字节作者need
2条回答

假设您处理的是8字节浮点数字。”压缩字节”在这个上下文中意味着有一个专用的内存块,其中前8个字节代表第一个浮点,然后紧接着的8个字节代表下一个浮点,以此类推,没有浪费。这是存储数据的最节省空间的方法(至少,没有压缩)。对于某些操作(例如,arraywise算术操作),它也可能是最节省时间的。在

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

最重要的区别可能是Python list,在它的底层C实现中,是一个容器,里面装满了指向对象的指针,而不是一个充满原始对象内容的容器。这意味着对同一Python对象的多个引用可以出现在list中。另一个是改变一个特定的项目可以非常有效地完成。例如,假设列表中的第一个项a[0]是一个整数,但您希望用占用更多内存的字符串替换它,例如a[0] = "There's a horse in aisle five."压缩数组必须(a)腾出额外的空间,移动内存中所有剩余的数组内容,以及(b)分别更新项目大小和类型的某种索引。但是Python list只需要用另一个指针值覆盖一个指针值。在

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

一般来说,没有绝对的“高效”或“低效”—问题在于您正在使用哪个资源,容器中有哪些内容类型(限制),以及您打算如何转换容器或其内容。在

在底层,Python主要使用指针。Python列表实际上是一个指针数组(至少在引用实现中是这样)。这也是效率低下的部分原因。另一部分是Python通常使用duck类型,因此在尝试之前,您无法判断某个操作是否会对列表元素起作用。在

当您访问一个列表元素来处理它时,例如调用__add__方法,您必须a)取消对实际对象的指针的引用,B)找出它是否具有__add__属性,检查它是否可调用,然后实际进行调用。在

在数组中,您知道预先存储的数据类型,因此您知道它的所有属性和所有操作。除此之外,所有实际的数字都被打包到一个单独的内存中。列表不是这样。因为数字在Python中只是一种对象类型,所以数字列表实际上是通用对象指针的列表。在

总而言之,数组存储的是原始数字,而不是指向大对象的指针,这些对象包装了数字,使其更小。数组预先知道其内容的类型,因此对整个数组应用操作只需要一次检查,而不是像列表那样对每个元素进行检查。在

相关问题 更多 >