Python 可以在内存中创建大型字典,但不能从文件中加载它们

标签 python dictionary

我的工作涉及使用 python defaultdict(set) 创建查找表。构建所有这些指令大约需要 20 分钟,并使用大约 2GB 的内存。我试图通过将所有这些指令写入 .py 文件然后通过导入将它们加载回来来节省时间。

我正在用 theFile.write("idToName = {}\n".format(dict(idToName))) 编写文件以删除 defaultdict< 的设置部分类。该文件大约有 500MB,所有的命令都可以正常工作。但是,当我尝试将文件重新导入时,它会填满我的内存并锁定所有内容。是什么导致了这种 ram 使用差异?

最佳答案

我猜您是在抓取计算机 RAM 的极限。当你将一个巨大的字典写入一个 .py 文件时,你当然也有一个巨大的 .py 文件。如果您现在尝试导入它,那么 Python 解释器需要做的不仅仅是将字典保存在内存中。它需要打开源文件,读取它,编译它,将它的字节码表示(编译结果)写入.pyc文件,然后执行它,最后在内存中重新创建字典。所有这些都意味着在内存中同时以多种格式保存数据。

我认为您的方法有缺陷。不应通过编写 .py 文件来存储数据。最好使用一种称为序列化的技术来存储它,有时也称为编码,对于 Python,也称为 pickling,因为它可以通过标准模块 pickle(或 cPickle 以获得更好的性能)来完成。

您应该在创建值后使用 pickle 模块存储您的(字典)。然后,当您再次需要它们时,再次从 pickle 存储文件中读取:

import pickle
value = create_my_huge_dictionary()
with open('my_dictionary.pickle', 'w') as store_file:
    pickle.store(store_file, value)

然后,也许在不同的脚本中:

import pickle
with open('my_dictionary.pickle') as store_file:
    value = pickle.load(store_file)

保留有关要删除的 defaultdict 的主题。上面提到的方法不会那样做。将 defaultdict 存储在 pickle 文件中并再次从那里读取值将重新创建一个 defaultdict,而不是 dict

我的建议是接受它,因为使用 defaultdict 而不是 dict 可能不会有什么坏处。但以防万一这不可行,您应该首先考虑不使用 defaultdict。您可以通过使用具有此模式的普通 dict 来实现它们的功能:

d = {}
d.setdefault('a', {}).setdefault('b', 4)
# d will now be {'a': {'b': 4}}

当然,您可以尝试在 pickle 之前或之后将您的 defaultdict convertdict。您可以通过简单地声明 d = dict(d) 来做到这一点。但这肯定意味着将它在内存中短暂保存两次。也许您的 RAM 不会受到影响,您又被卡住了。

如果你使用 json 来存储你的字典(也许这很简单),那么它曾经是一个 defaultdict 的信息在序列化后也会消失.

关于Python 可以在内存中创建大型字典,但不能从文件中加载它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47891623/

相关文章:

python - 尝试索引字符串列表并根据其索引删除字符串

Python:如何按子字符串相关性对字符串列表进行排序?

python - 将文件更改为列表更改为字典

python - 如果新值是较晚的日期,则替换字典中的值

Python 3 - 从字典中打印特定列表项

python - 删除元素后刷新 QListWidget

python - 在 Huggingface BERT 模型之上添加密集层

python - Django 检查发布日期是否在模型的两个日期之间

python - 计算字典中的单词数(Python)

python - 如果值相同,如何对字典中的键进行排序?