420

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

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

是为了性能和内存优化,还是我遗漏了一些明显的东西?

4

11 回答 11

479

基本上,Python 列表非常灵活,可以保存完全异构的任意数据,并且可以在摊销的常数时间内非常有效地附加它们。如果您需要高效且轻松地缩小和增加列表,那么它们就是您的最佳选择。但是它们比 C 数组使用更多的空间,部分原因是列表中的每个项目都需要构造一个单独的 Python 对象,即使对于可以用简单的 C 类型(例如floatuint64_t)表示的数据也是如此。

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 数据数组时很有用。

于 2008-10-06T23:11:06.897 回答
69

对于几乎所有情况,普通列表都是正确的选择。arrays 模块更像是 C 数组的薄包装器,它为您提供了一种强类型容器(请参阅docs),可以访问更多类似 C 的类型,例如有符号/无符号短或双精度,它们不是内置的一部分-输入类型。我会说只有当你真的需要它时才使用数组模块,在所有其他情况下坚持使用列表。

于 2008-10-06T20:24:38.823 回答
55

如果您不知道为什么要使用它,数组模块是您可能不需要的东西之一(请注意,我并不是要以居高临下的方式这么说!) . 大多数时候,数组模块用于与 C 代码接口。为了更直接地回答您关于性能的问题:

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

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

TL;DR 如果您有特殊的优化需求或者您需要与 C 代码交互(并且不能使用pyrex),我只会使用数组。

于 2008-10-07T14:00:40.390 回答
21

这是一个权衡!

每个人的优点:

列表

  • 灵活的
  • 可以是异质的

数组(例如:numpy 数组)

  • 统一值数组
  • 同质
  • 紧凑(尺寸)
  • 高效(功能和速度)
  • 方便的
于 2017-01-30T20:18:07.667 回答
13

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

于 2008-10-06T20:22:50.527 回答
8

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

于 2008-10-07T13:47:01.980 回答
6

如果您要使用数组,请考虑使用 numpy 或 scipy 包,它们为您提供了更多灵活性的数组。

于 2008-10-06T20:30:54.347 回答
6

关于性能,这里有一些比较 python 列表、数组和 numpy 数组的数字(所有这些都在 2017 Macbook Pro 上使用 Python 3.7)。最终结果是 python 列表对于这些操作是最快的。

# Python list with append()
np.mean(timeit.repeat(setup="a = []", stmt="a.append(1.0)", number=1000, repeat=5000)) * 1000
# 0.054 +/- 0.025 msec

# Python array with append()
np.mean(timeit.repeat(setup="import array; a = array.array('f')", stmt="a.append(1.0)", number=1000, repeat=5000)) * 1000
# 0.104 +/- 0.025 msec

# Numpy array with append()
np.mean(timeit.repeat(setup="import numpy as np; a = np.array([])", stmt="np.append(a, [1.0])", number=1000, repeat=5000)) * 1000
# 5.183 +/- 0.950 msec

# Python list using +=
np.mean(timeit.repeat(setup="a = []", stmt="a += [1.0]", number=1000, repeat=5000)) * 1000
# 0.062 +/- 0.021 msec

# Python array using += 
np.mean(timeit.repeat(setup="import array; a = array.array('f')", stmt="a += array.array('f', [1.0]) ", number=1000, repeat=5000)) * 1000
# 0.289 +/- 0.043 msec

# Python list using extend()
np.mean(timeit.repeat(setup="a = []", stmt="a.extend([1.0])", number=1000, repeat=5000)) * 1000
# 0.083 +/- 0.020 msec

# Python array using extend()
np.mean(timeit.repeat(setup="import array; a = array.array('f')", stmt="a.extend([1.0]) ", number=1000, repeat=5000)) * 1000
# 0.169 +/- 0.034
于 2020-06-16T01:38:23.290 回答
5

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

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

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

于 2008-10-06T20:25:05.013 回答
5

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

  1. 这两种数据类型之间的主要区别在于您可以对它们执行的操作。例如,您可以将一个数组除以 3,它将数组的每个元素除以 3。列表不能这样做。

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

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

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

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

于 2019-09-10T13:26:59.783 回答
0

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

于 2018-07-17T00:46:44.200 回答