我的工作涉及使用 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
convert 为 dict
。您可以通过简单地声明 d = dict(d)
来做到这一点。但这肯定意味着将它在内存中短暂保存两次。也许您的 RAM 不会受到影响,您又被卡住了。
如果你使用 json
来存储你的字典(也许这很简单),那么它曾经是一个 defaultdict
的信息在序列化后也会消失.
关于Python 可以在内存中创建大型字典,但不能从文件中加载它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47891623/