Python列表占用了太多内存

时间:2014-11-29 06:38:46

标签: python memory

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

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

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

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

Ex:tic-tac-toe的简化示例。

x| |o
 | | 
o| | 

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

2 个答案:

答案 0 :(得分:2)

我刚刚在Python 3.4(64位)上测试过它。

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

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

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

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

也许您需要考虑采用不同的方法解决问题。您并不需要存储所有这些状态 - 很容易计算该列表中的项目编号123456,因此您可能只需要存储在程序期间修改的项目编号。跑了?

答案 1 :(得分:2)

itertools.product返回一个迭代器。转换到列表是使用大量内存的步骤。你能编写算法来迭代产品而不存储它吗?像

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