保存/加载字典,同时保存密钥的数据类型

时间:2016-05-27 10:02:14

标签: python json dictionary

我想保存一个包含字符串和整数键以及多个数据类型值的字典。例如:

dData = {
    'a': ['c','d'],
    1: [5.1, 3.1]
}

要保存并加载它,我使用json.dumpjson.load,但是,我的整数键在加载时会转换为字符串。

我不想改变字典的创建方式,因为将这些键保持为整数非常方便。

如何将字典保存到文件中,然后在保存类型时再次加载?

2 个答案:

答案 0 :(得分:3)

我建议使用shelve模块。

Shelve 允许您在磁盘文件中存储任意python对象的字典。

他们的文档中的一个例子:

with shelve.open('spam') as db:
    db['eggs'] = 'eggs'

它没有回答你的整数键的情况,你可以为它创建一个shelve的子类,它将int转换为字符串或完全使用pickle。

这是一个子类示例:

from shelve import DbfilenameShelf

class IntShelf(DbfilenameShelf):

    def __getitem__(self, key):
        # Not isinstance as we wish to be specific
        if type(key) == int:
            key = "i" + str(key)
        elif type(key) == str:
            key = "s" + key
        else:
            raise TypeError

        return super().__getitem__(key)

    def __setitem__(self, key, value):
        if type(key) == int:
            key = "i" + str(key)
        elif type(key) == str:
            key = "s" + key
        else:
            raise TypeError

        return super().__setitem__(key, value)

用法:

>>> db = IntShelf("testdb")
>>> db["123"] = "foo"
>>> db[123] = ["bar", "bar", "bar"]
>>> db["123"]
'foo'
>>> db[123]
['bar', 'bar', 'bar']

请记住,使用pickle而不是搁置来存储字典有许多缺点:

  1. 您需要一次加载整个字典,在大型数据集的情况下消耗大量内存。
  2. 更改单个值,需要重写整个字典。
  3. Shelve拥有比在整个地方使用泡菜更清晰的界面,并且具有内部缓存以实现最高效率。
  4. 如果程序在中间崩溃,如果你没有使用finally子句包装整个数据库,则会松开数据库,而在搁置时,数据库会按需保存。
  5. 请记住,磁盘访问是程序中最慢的部分之一,因此您希望将其最小化。

答案 1 :(得分:0)

感谢指向其他问题的指针等,尽管使用picke 的答案非常简单(为什么会这样;我错过了一个细节?)。

sTestDataPath = "/path/to/data/test_data.p"
import pickle


with open(sTestDataPath, 'w') as f:
    pickle.dump(dInputData, f)

with open(sTestDataPath, 'r') as f:
    dInputData = pickle.load(f)