Python列表与数组-何时使用?


374

如果要创建一维数组,则可以将其实现为列表,也可以使用标准库中的“数组”模块。我一直将列表用于一维数组。

我想改用数组模块的原因或情况是什么?

是为了性能和内存优化,还是我缺少明显的东西?

Answers:


438

基本上,Python列表非常灵活,可以保存完全不同的任意数据,并且可以在摊销后的固定时间内非常高效地附加到它们。如果您需要高效而又省时地缩小和扩展列表,则可以采用这些方法。但是它们比C数组占用更多的空间

array.array类型,在另一方面,是只在C数组的薄包装。它只能保存所有相同类型的同类数据,因此仅使用sizeof(one object) * length内存字节。通常,在需要将C数组公开给扩展名或系统调用(例如ioctlfctnl)时,应使用它。

array.array也是在Python 2.x()中表示可变字符串的一种合理方法array('B', bytes)。但是,Python 2.6+和3.x提供了一个可变字节字符串bytearray

但是,如果要对数字数据的均质数组进行数学运算,则最好使用NumPy,它可以自动对复杂的多维数组进行矢量化操作。

简而言之array.array当您需要除数学之外的其他原因而需要同构C数据数组时,此选项很有用。


9
numpy.ndarray是否具有与array.array相同的内存占用量?
Gordon Bean

6
@Gordon,在大而连续的数组的情况下应该非常相似:它们都将需要sizeof(element)×(元素数)个字节,再加上一个小的固定报头来管理开销。但是,ndarray有一些用于处理不连续和稀疏数组的高级选项,我认为一些为大型数组分配内存的可插拔策略...其中一些高级功能将使其占用更少的内存,而其他一些功能将通过使用更多功能来提高性能记忆。
Dan Lenski 2014年

当内存出现问题时,例如使用micropython对微控制器编程时,也很有用
janscas

可以在恒定时间内查找数组的第i个元素,而在链表中,在最坏的情况下它的顺序为“ n”。python列表中第i个元素的查找时间是多少?
Nithish追求幸福

7
@ NithishInpursuitOfhappiness,Python列表不是链接列表。它在内部表示为数组,并且具有与Java的ArrayList相同的时间复杂度特征。因此,获取和设置Python列表的第i个元素需要花费恒定的时间。将元素追加到Python列表需要固定的摊销时间,因为当数组空间不足时,数组大小将增加一倍。在Python列表中间插入元素或从其中删除元素需要O(n)时间,因为需要移动元素。有关参考,请参阅:wiki.python.org/moin/TimeComplexity
geofflee

66

在几乎所有情况下,正常列表都是正确的选择。数组模块更像是C数组的一个薄包装器,它为您提供了一种强类型的容器(请参阅docs),可以访问更多类似C的类型,例如有符号/无符号short或double,这不是构建的一部分-in类型。我说只有在确实需要时才使用arrays模块,在所有其他情况下,都坚持使用列表。


3
可能,虽然从未真正使用过它,但是运行一些微基准测试会很有趣。
安德烈(André)

13
实际上,我进行了一个快速测试-我定时将一个包含100M条目的列表和一个与相应数组进行的相同测试相加,该列表实际上快了约10%。

38
列表速度更快,因为在读取或写入数组时,对数组“原始”数据的操作需要不断创建和销毁python对象。
tzot

7
正如我在上面的回答中所指出的那样,@ Moe 不是 Python的内置array函数,而是用于数学运算。如果您尝试使用NumPy ndarray求和一个10 ^ 8的数字数组,它将完全list消失。@tzot对内置array函数为何运算速度较慢有正确的想法。
Dan Lenski 2014年

2
我刚刚进行了测试,我的计算机上numpy的速度提高了86.6倍。
2016年

53

如果您不知道为什么要使用它,那么数组模块就是其中一种您可能不需要的东西(请注意,我并不是要以居高临下的方式来说明这一点!) 。大多数时候,数组模块用于与C代码进行接口。为您提供有关性能问题的更直接答案:

对于某些用途,数组比列表更有效。如果需要分配一个您不会更改的数组,那么数组可以更快并且使用更少的内存。GvR有一个优化轶事,其中阵列模块是赢家(长期阅读,但值得)。

另一方面,列表消耗的内存比数组多的部分原因是因为当所有分配的元素都被使用时,python将分配一些额外的元素。这意味着将项目追加到列表的速度更快。因此,如果您计划添加项目,则要使用列表。

TL; DR如果您有特殊的优化需求或需要与C代码进行接口(并且不能使用pyrex),则仅使用数组。


1
+1为具体示例,并提及速度优势。最重要的答案让我感到疑惑,“是否存在时间记忆权衡?” 和“这有什么用,这不是一个很深奥的低内存情况?”
leewz 2014年

@leewz确切地说,这应该被视为答案。
Gauri Shankar Badola

21

这是一个权衡!

每个人的优点:

清单

  • 灵活
  • 可以是异构的

数组(例如:numpy数组)

  • 统一值数组
  • 同质
  • 紧凑(尺寸)
  • 高效(功能和速度)
  • 方便

2
问题是在python中的数组模块;不是numpy数组。他们除了大小效率方面没有很多优点。他们并不快。
NONONONONO

14

我的理解是,数组的存储效率更高(例如,内存的连续块与指向Python对象的指针),但是我不知道任何性能上的好处。另外,对于数组,您必须存储相同类型的原语,而列表可以存储任何内容。


8

标准库数组对于二进制I / O很有用,例如将整数列表转换为要写入例如wave文件的字符串。也就是说,正如许多人已经指出的那样,如果您要进行任何实际工作,则应考虑使用NumPy。



5

数组只能用于特定类型,而列表可以用于任何对象。

数组也只能是一种类型的数据,而列表可以具有各种对象类型的条目。

数组对于某些数值计算也更加有效。


4
内置的python数组在性能方面不是高效的,而仅是内存方面的。
tzot

在某些情况下,数组在处理方面更有效。请参阅下面的我的文章: stackoverflow.com/questions/176011/…–
杰森·贝克

0

numpy数组和list之间的重要区别是,数组切片是原始数组上的视图。这意味着不会复制数据,并且对视图的任何修改将反映在源数组中。


0

这个答案将总结几乎所有有关何时使用List和Array的查询:

  1. 这两种数据类型之间的主要区别是可以对它们执行的操作。例如,您可以将数组除以3,然后将数组的每个元素除以3。使用列表无法完成相同的操作。

  2. 该列表是python语法的一部分,因此不需要声明它,而您必须在使用它之前声明该数组。

  3. 您可以将不同数据类型的值存储在列表中(异构),而在Array中,您只能存储相同数据类型的值(异构)。

  4. 数组具有丰富的功能和快速的功能,与列表相比,它广泛用于算术运算和存储大量数据。

  5. 与列表相比,数组占用的内存更少。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.