如何cPickle转储并将单独的词典加载到同一个文件?

时间:2012-07-25 01:33:39

标签: python dictionary pickle

我有一个运行并创建三个词典的过程:2个相当小,1个大。

我知道我可以存储一个字典,如:

import cPickle as pickle
with open(filename, 'wb') as fp:
  pickle.dump(self.fitResults, fp)

我想要做的是将所有3个词典存储在同一个文件中,并能够在另一个时间单独加载三个词典。像

这样的东西
with open(filename, 'rb') as fp:
  dict1, dict2, dict3 = pickle.load(fp)

或者甚至更好地加载前两个词典,并使其可选择是否加载第三个(大)词典。这是可能的,还是应该以完全不同的方式解决这个问题?

3 个答案:

答案 0 :(得分:23)

当然,您只需将每个单独转储,然后单独加载:

with open(filename,'wb') as fp:
    pickle.dump(dict1,fp)
    pickle.dump(dict2,fp)
    pickle.dump(dict3,fp)

with open(filename,'rb') as fp:
    d1=pickle.load(fp)
    d2=pickle.load(fp)
    d3=pickle.load(fp)

确保将最后一个转移到最后,这样你就可以加载小的一个而不先加载大的那个。我想你甚至可以聪明地存储每个转储在各种标题中开始的文件位置,然后你可以在加载之前寻找那个位置(但这开始变得有点复杂)。

答案 1 :(得分:6)

我推荐经常忘记的shelve模块,它有效地为您提供了由Berkley DB文件或dbm文件支持的持久字典(由anydbm选择)。 db应该提供性能改进(对于你的大词典)。

使用示例:

import shelve
shelf = shelve.open('my_shelf')
>>> shelf
{}

# add your dictionaries (or any pickleable objects)
shelf['dict1'] = dict(a=10, b=20, c=30, l=[10, 20, 30])
shelf['dict2'] = dict(a=100, b=200, c=300, l=[100, 200, 300])
shelf['dict3'] = dict(a=1000, b=2000, c=3000, l=[1000, 2000, 3000])

>>> shelf
{'dict1': {'a': 10, 'c': 30, 'b': 20, 'l': [10, 20, 30]}, 'dict3': {'a': 1000, 'c': 3000, 'b': 2000, 'l': [1000, 2000, 3000]}, 'dict2': {'a': 100, 'c': 300, 'b': 200, 'l': [100, 200, 300]}}
shelf.close()

# then, later
shelf = shelve.open('my_shelf')
>>> shelf
{'dict1': {'a': 10, 'c': 30, 'b': 20, 'l': [10, 20, 30]}, 'dict3': {'a': 1000, 'c': 3000, 'b': 2000, 'l': [1000, 2000, 3000]}, 'dict2': {'a': 100, 'c': 300, 'b': 200, 'l': [100, 200, 300]}}

答案 2 :(得分:3)

正如前面提到的here,你可以将几个对象腌制到同一个文件中,然后加载它们(按照相同的顺序):

f = file(filename, 'wb')
for obj in [dict1, dict2, dict3]:
    cPickle.dump(obj, f, protocol=cPickle.HIGHEST_PROTOCOL)
f.close()

然后:

f = file(filename, 'rb')
loaded_objects = []
for i in range(3):
    loaded_objects.append(cPickle.load(f))
f.close()

您可以按特定顺序保存词典,以便在加载词典时,您可以选择仅选择首选词典。

例如,如果您按顺序存储字典:smallDict1smallDict2largeDict1
通过在加载时设置适当的范围,您只能加载小的 (这里for i in range(2) ...