python - 向 python 字典分配和更新值时总是出现内存错误

标签 python dictionary error-handling

我需要使用一种复杂的字典并动态更改某些键的值。 所以我尝试了以下方法,但遇到了大约 32GB RAM 的 MemoryError 。 sys.getsizeof(d) 返回 393356,sys.getsizeof(d.items()) 为 50336。 我是否以错误的方式使用了 python dict?谁能帮助我!?

d=nltk.defaultdict(lambda:nltk.defaultdict(float))
for myarticlewords in mywords:
    for i in myarticlewords:
        for j in myarticlewords:
            d[i][j]+=1.0   

回溯停止于“d[i][j]+=1.0”

当我尝试时:

dd=dict( (i,d[i].items() ) for i in d.keys() )

Traceback (most recent call last):
    File "<pyshell#34>", line 1, in <module>
    dd=dict( (i,d[i].items() ) for i in d.keys() )
   File "<pyshell#34>", line 1, in <genexpr>
   dd=dict( (i,d[i].items() ) for i in d.keys() )
MemoryError

谢谢!

最佳答案

您似乎使用的是 32 位版本的 python。如果您运行的是 Windows,您可能已经点击了 windows memory limit对于 32 位程序,为 2GB。

这与我根据一些有根据的猜测计算出的数字相符。首先,一些重要的事实:getsizeof 仅返回字典本身的大小,而不是存储在其中的内容的大小。所有“容器”类型都是如此。此外,在添加了如此多的项目后,词典的大小会以交错的方式增加。

现在,当我存储大约 5500 到 21000 个项目的字典时,getsizeof 返回 786712 - 即 393356 * 2。我的 Python 版本是 64 位,因此这强烈表明您正在使用 32 位版本的 Python 存储 5500 到 21000 个项目。您正在使用 nltk,这表明您在此处存储单词二元图。这意味着您至少有大约 5500 个单词。您将为每个单词存储第二个字典,这也是一个包含 5500 项的字典。因此,这里真正拥有的是 393356 + 393356 * 5500 字节,加上至少 5500 * 20 字节用于字存储。总结一下:

>>> (393356 + 393356 * 5500 + 5500 * 20) / 1000000000.0
2.163961356

您正在尝试存储至少 2GB 的数据。简而言之,如果你想利用这 32 GB 内存,你应该升级到 64 位版本的 Python。

<小时/>

我要补充一点,如果您关心性能,您可能只想使用 pickle (或 cPickle)而不是 shelve 存储字典。即使您设置了 writeback=True,shelve 也可能会变慢。

>>> shelve_d = shelve.open('data', writeback=True)
>>> normal_d = {}
>>> def fill(d):
...    for i in xrange(100000):
...        d[str(i)] = i
...        
>>> %timeit fill(shelve_d)
1 loops, best of 3: 2.6 s per loop
>>> %timeit fill(normal_d)
10 loops, best of 3: 35.4 ms per loop

pickle保存字典自然也会花费一些时间,但至少它不会减慢计算本身。

关于python - 向 python 字典分配和更新值时总是出现内存错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11883634/

相关文章:

python - 将整数转换为给定字母表上的字符串的算法

php - Paypal -快速结帐-购物车项目金额总计与订单金额不符(10413)

python - 字典文字的评估顺序

javascript - 如何使用函数和文本映射 ReactJs

python - 在Heroku上的python worker进程中使用try语句来处理由于对等错误而导致的连接重置是否理想?

tsql - 尝试…将错误捕获到错误日志表中

python - 大多数库什么时候会兼容 Python 3?

python - HPC : comm. 上的 mpi4py 收集

python - Eventlet 的生成不起作用。这么奇怪

java - 了解使用 map 和 vector 时垃圾收集器在 Java 7 中的工作原理