【问题标题】:Preallocate very large array in Python leads to MemoryError在 Python 中预分配非常大的数组会导致 MemoryError
【发布时间】:2017-12-04 20:01:31
【问题描述】:

我正在尝试在 python 中预分配一个列表

c=[1]*mM #preallocate array

我的问题是我遇到了 MemoryError,因为

mM=4999999950000000

解决这个问题的最佳方法是什么。我正在考虑创建一个新对象,将我的列表拆分为大约500000000 的值。 这是我应该做的还是有创建具有大量输入的数组的最佳实践?

【问题讨论】:

  • 您需要大约 5 PB 的内存来存储它。
  • 是的。你到底想用这个来完成什么?此外,如果您使用的是 Linux,那么您可以执行类似 this with memory swapping. 的操作
  • 您的实际问题是什么。为什么需要创建一个大小为 4999999950000000 的数组/列表?正如所指出的。这将需要 5PB 的存储空间..
  • 如果您假设 Python 中的整数是 4 个字节(一个整数消耗的内存量在需要时可能会急剧增加),您需要超过 20 个 PB内存来存储该数据。
  • @GhilasBELHADJ 实际上,在 64 位系统上,您需要 40 PB。仅针对 list 对象中的底层数组:4999999950000000 *1e-9*8,加上 Python 开销,加上额外的空间......

标签: python arrays list python-3.x memory


【解决方案1】:

使用生成器

您正在尝试创建一个您很可能无法放入计算机内存的对象。如果您确实需要表示该长度的列表,您可以使用生成器来根据需要动态生成值。

def ones_generator(length):
    for _ in range(length):
        yield 1

gen = ones_generator(4999999950000000)
for i in gen:
    print(i)  # prints 1, a lot

注意:该问题已标记为 Python 3,但如果您使用的是 Python 2.7,则需要使用 xrange 而不是 range

使用字典

根据您的问题,您实际上不需要预先分配该长度的列表,但您希望在非常大的索引处非常稀疏地存储值。此模式与 Python 中的 dict 类型匹配程度高于 list。您可以简单地将值存储在字典中,而无需预先分配它们的键/空间,Python 会在后台为您处理。

dct = {}
dct[100000] = "A string"
dct[592091] = 123
dct[4999999950000000] = "I promise, I need to be at this index"

print(dct[4999999950000000])
# I promise, I need to be at this index

在该示例中,我只存储了 strint 值,但它们可以是 Python 中的任何对象。最好的一点是,该字典不会根据最大索引消耗内存(就像 list 那样),而是根据其中存储的值的数量。

【讨论】:

  • 问题被标记为 Python 3,所以你没有 xrange 只是 range
  • @juanpa.arrivillaga 谢谢,我更新了答案以包含有关 python 版本的注释。
  • 好吧,因为我真的没有 5 PB 我更喜欢你的 dict 解决方案。我真的只需要在某些位置定义值
猜你喜欢
  • 2021-01-29
  • 2021-07-24
  • 2013-12-23
  • 1970-01-01
  • 2017-10-18
  • 1970-01-01
  • 2019-02-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多