【问题标题】:Can array.array() be used to define a 2d array?array.array() 可以用来定义二维数组吗?
【发布时间】:2014-03-07 10:52:51
【问题描述】:

我是 Python 新手。我正在使用 Python 2.7。 我想创建一个二维数组,我知道如何使用列表。但是使用列表数据很大。 为了节省内存,我想使用数组而不是列表。 这受到了启发 在Huge memory usage of loading large dictionaries in memory 的答案中给出的“使用array.array('l') 而不是列表的(整数)值”。

这种方法可以用于二维数组吗?

【问题讨论】:

  • 如果您还没有,请查看numpynumpy.orgNumpy 的数组是多维的(不仅仅是 1、2 或 3d,而是 N-d)、内存高效(与 array.array 一样高效)容器。

标签: python arrays python-2.7 2d


【解决方案1】:

您提到的问题是关于字典,而不是数组。无论如何,你可以这样做,这会创建一个 listarrays 初始化为零的 4 字节整数,这实际上是一个 2Darray

from array import array

width, height = 1000, 1000
array2d = [array('l', (0 for _ in xrange(width))) for _ in xrange(height)]

array2d[999][999] = 42

【讨论】:

  • answer 引用了Use array.array('l') instead of list for the (integer) value
  • @Noelkd:哎呀。是的,对于 4 字节整数,它需要输入代码 'l' -- 谢谢。
  • 感谢 Martineau,但是当我检查 array2d 和 array_list = [[0 for _ in xrange(width)] for _ in xrange(height)] 的大小时,它们是相同的。在我看来,参数“使用array.array('l')而不是(整数)值的列表”可以节省内存是不成立的。我的理解错了吗?
  • Shirley:使用array.array('l')——一个 4 字节整数的数组——在链接问题的答案中节省了内存,因为它被用来代替存储“似乎是一个整数”。那是特定于那种情况下的数据的东西。基本思想可能适用于其他情况,具体取决于所存储数据的性质。
  • 雪莉:P.S. sys.getsizeof(array_list)sys.getsizeof(array2d) 返回相同的值,因为它们都没有计算每行中元素的大小。 1000x1000 4 字节整数将需要至少 4,000,000 字节的内存。您可以通过sys.getsizeof(array('i', (0 for _ in xrange(width*height)))) 的值来查看这一点。使用类似的东西并手动进行二维索引可能是最节省空间的方法。如果您有兴趣,我可以添加另一个答案来说明如何做到这一点。
【解决方案2】:

您不能真正创建 2darray.array(),因为它们的元素仅限于以下类型:字符、整数和浮点数。相反,您可以将数据存储在常规的一维数组中,并通过一些辅助函数访问它。

下面是我试图描述的插图:

from array import array

INFO_SIZE = 3  # number of entries used to store info at beginning of array
WIDTH, HEIGHT = 1000, 1000  # array dimensions
array2d = array('l', (0 for _ in xrange(INFO_SIZE + WIDTH*HEIGHT)))
array2d[:INFO_SIZE] = array('l', (INFO_SIZE, WIDTH, HEIGHT))  # save array info

def get_elem(two_d_array, i, j):
    info_size = two_d_array[0]
    width = two_d_array[1]
    return two_d_array[info_size + j*width + i]

def set_elem(two_d_array, i, j, value):
    info_size = two_d_array[0]
    width = two_d_array[1]
    two_d_array[info_size + j*width + i] = value

import sys
print format(sys.getsizeof(array2d), ",d")  # 4,091,896

print get_elem(array2d, 999, 999)  # 0
set_elem(array2d, 999, 999, 42)
print get_elem(array2d, 999, 999)  # 42

如您所见,array2d 的大小(相对而言)仅略大于数据本身的大小(在本例中为 4,000,000 字节)。您可以完全放弃这些函数,只需在线进行偏移计算,以避免在每次访问时调用函数来执行它的开销。另一方面,如果这不是一个大问题,您可以更进一步,将所有逻辑封装在一个通用的 class Array2D 中。

【讨论】:

    【解决方案3】:

    在 python 中,数组是列表。

    另一个问题中的内存优势来自不使用字典。

    一般来说,“从列表到二维数组”的移动不会节省内存。

    给我你的数据样本,我会更新我的答案。

    【讨论】:

    • array.array,不是指内置的list
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-29
    • 1970-01-01
    相关资源
    最近更新 更多