【问题标题】:Python list takes up too much memoryPython列表占用太多内存
【发布时间】:2014-11-29 06:38:45
【问题描述】:

如果我在 python 中执行这些代码行:

states = itertools.product("012",repeat = 16)
states = list(states)

然后我用的内存比我笔记本电脑上的还多。有没有解决的办法?我需要这个状态列表,这样当我生成一个新状态时,我可以更新它在列表中的值。

编辑: 我将这些状态存储为 4x4 网格,其中 0、1 和 2 是网格上每个正方形的可能状态。存储的值实际上是一个 16 长的列表,它说明了从当前状态移动到网格上的任何方块的奖励是什么。用 -np.inf 标记不可能的动作。随着游戏的进行,导致从某些状态获胜的动作的奖励会增加,因此机器人更有可能在未来做出该动作。

例如:井字游戏的简化示例。

x| |o
 | | 
o| | 

此状态将被转换为一个 9 长列表“102000200”,然后在所有可能状态的列表中查找它以查看下一个最佳移动是什么。在这种情况下,这将是 x 的中间位置。

【问题讨论】:

  • 更清楚地描述您的问题。什么状态?更新什么值?
  • 大约有 4300 万个州。您能否不使用稀疏表示,例如一个字典(或defaultdict),其中每个键将是一个字符串元组(或者只是字符串,或者假设字符串是基数为3的数字的整数)?
  • 更新了更多信息。我不确定字典将如何节省空间,是否仍会存储尽可能多的值?

标签: python memory


【解决方案1】:

我刚刚在 Python 3.4(64 位)上对此进行了测试。

结果列表很大,但并不庞大(或者看起来如此):

>>> import itertools, sys
>>> states = itertools.product("012",repeat = 16)
>>> s = list(states)
>>> sys.getsizeof(s)
357571088

我最初关于字符串列表会更小的推测是不正确的——这并没有太大的区别。

但是,我可以看到,在调用list 之后,Python 的内存使用量从 4 MB(启动后)增加到大约 8 GB,并且它只在del(s) 之后返回到基线状态,而不是在gc.collect() 之后因此,如此庞大的多元素列表似乎存在一些巨大的开销。这可能与 Alex Martelli 描述的 here 有关,在这种情况下,任何 Python 解决方案都会变得相当复杂。

也许您需要考虑一种不同的方法来解决问题。您实际上并不需要存储所有这些状态 - 很容易计算出该列表的第 123456 项将是什么,所以也许您只需要存储在程序运行期间修改的那些?

【讨论】:

  • 我确实考虑过一种方法,您只存储实际生成的状态,但我的算法使用对机器人未来移动的预测。如果没有初始化该值,则无法预测未来的移动。
【解决方案2】:

itertools.product 返回一个迭代器。转换为列表是使用大量内存的步骤。您可以编写算法来迭代产品而不存储它吗?喜欢

for tuple16 in itertools.product("012", repeat = 16):
    do_something(tuple16)

【讨论】:

  • 很遗憾,我需要一个查找表。
猜你喜欢
  • 2013-07-11
  • 2020-05-18
  • 1970-01-01
  • 1970-01-01
  • 2017-04-14
  • 2015-10-14
  • 2013-07-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多