python字典可以包含多少个元素?

时间:2013-10-10 04:32:56

标签: python dictionary out-of-memory

我使用Windows 7 64位和Python 2.7 32位在python控制台中得到以下输出:

>>> a = {}
>>> for k in xrange(1000000): a[k] = k
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
MemoryError
>>> len(a)
21846
>>> a[21846]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 21846
>>> a[21846] = 21846
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
MemoryError

为什么我不能添加超过21846项dict?

这个号码的具体内容是什么(2 * 3 * 11 * 331)?

注意:我的内存比sys.getsizeof(a)== 393356

多得多

3 个答案:

答案 0 :(得分:6)

非常令人惊讶!关于21846,Python并没有什么特别之处。这里是32位Windows Vista与Python 2.7.5以及适度的3 GB RAM:

>>> a = {}
>>> for k in xrange(1000000): a[k] = k
...
>>> len(a)
1000000

也可以用1000万。但这是从一个新的控制台窗口开始的。也许你在向我们展示之前做了其他的事情,并留下了一些大型数据结构?按现代标准来看,21846很小; - )

后来

这是发布到Python的错误跟踪器,在这里:http://bugs.python.org/issue19246

它被关闭为“不会修复”,因为同样的行为被一个简单的小纯C程序重现。也就是说,系统C的malloc()free()是罪魁祸首,而且Python无法做到这一点。它似乎特定于Windows,使用Microsoft的C库。问题是堆碎片:在分配和释放许多不同大小的对象之后,系统malloc()在被要求“大”的内存块时失败,尽管有大量可用的空闲字节。但它们不在一个连续的块中(至少不是系统中malloc()认可的那个)。

发生了事情; - )

答案 1 :(得分:2)

这是您的环境约束,与Python词典无关。因此,您的问题的答案是:python字典可以保存尽可能多的环境。

答案 2 :(得分:2)

正如@Leifingson和@Tim所提到的,这种行为取决于之前完成的事情。为了说明内存消耗,我将使用以下示例:

Python 2.7 (r27:82525, Jul  4 2010, 09:01:59) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> a = {}
>>> for k in xrange(1000000): a['a' * k] = k
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
MemoryError
>>> len(a)
64036

如果我们采用摘要密钥长度:

>>> log(sum(xrange(64036)), 2)
30.93316861532543

我们接近整数溢出!

棘手的部分是:

>>> import sys
>>> sys.getsizeof(a)
1573004

sys.getsizeof返回不同内容的大小,然后返回所有dict项。也许这是所有关键哈希的大小,我不知道。

完成后,

>>> a = {}

将释放所有2 Gb的已分配内存,但会将GC(我责备它)置于某种残缺状态。执行:

>>> for k in xrange(1000000): a[k] = k

将导致:

MemoryError

类似于问“魔法”号码:

>>> len(a)
87382