字典嵌套字典的JSON编码

4

假设我有一个由基本字典组成的自定义数据结构,我需要使用JSON进行序列化。我的结构如下:

path_list_dict = {(node1, node2 .. nodeN): (float1, float2, float3)}

因此,这是用一个元组进行键控,并且其值是由三个值组成的元组。 键中的每个节点元素都是一个自定义类对象,具有为其编写的 _str_ 方法。标识路径列表字典中每个字典条目的包装器字典如下:

path_options_dict = {‘Path1’: {(node1, node2 .. nodeN): (float1, float2, float3)}, ‘Path2’: {(nodeA1, nodeA2 .. nodeAN): (floatA1, floatA2, floatA3)} }

等等其他情况。

当我尝试使用JSON进行序列化时,当然会遇到TypeError,因为内部字典具有元组作为键和值,而字典需要将键作为字符串才能进行序列化。这可以通过将str(tuple)表示插入到字典中来轻松解决。

我所关心的是,当我接收它并解压缩值时,我将在接收端拥有所有字符串。内部字典的键元组由自定义类元素组成,现在表示为一个str。我能恢复嵌入式数据吗?还是有更好的方法来做这件事?

为了更清晰地说明,我正在使用此JSON教程作为参考。

1个回答

2
你有几个选择:
  • Serialize with a custom key prefix that you can pick out and unserialize again:

    tuple_key = '__tuple__({})'.format(','.join(key))
    

    would produce '__tuple__(node1,node2,nodeN)' as a key, which you could parse back into a tuple on the other side:

    if key.startswith('__tuple__('):
         key = tuple(key[10:-1].split(','))
    

    Demo:

    >>> key = ('node1', 'node2', 'node3')
    >>> '__tuple__({})'.format(','.join(key))
    '__tuple__(node1,node2,node3)'
    >>> mapped_key = '__tuple__({})'.format(','.join(key))
    >>> tuple(mapped_key[10:-1].split(','))
    ('node1', 'node2', 'node3')
    
  • Don't use dictionaries, use a list of lists:

    {'Path': [[[node1, node2 .. nodeN], [float1, float2, float3]], [...]]}
    

    You can build such a list simply from the dict.items() result:

    >>> json.dumps({(1, 2, 3): ('foo', 'bar')}.items())
    '[[[1, 2, 3], ["foo", "bar"]]]'
    

    and when decoding, feed the whole thing back into dict() while mapping each key-value list to tuples:

    >>> dict(map(tuple, kv) for kv in json.loads('[[[1, 2, 3], ["foo", "bar"]]]'))
    {(1, 2, 3): (u'foo', u'bar')}
    
后一种方法也适用于自定义类,因为JSONEncoder.default() 方法仍将把这些自定义对象交给您来序列化回适当的字典对象,这意味着传递给JSONDecoder()的适当object_hook可以再次返回完全反序列化的自定义对象。

谢谢你的帮助。我使用字典的第二种方法是因为路径是唯一的,我需要这些键来检索它们进行一些处理。第一个字典用于内部路径查找,这些字典中的键是唯一的。我需要在另一个模块中选择其中一条路径,并且必须确定选择了哪条路径以进行更多的后处理,这就是为什么我使用包装器的原因。第二种方法无法帮助我确定选择了哪条路径。因此,我使用这种方法。另外,请您能否详细说明一下第一种方法? - adwaraki
请原谅我的幼稚。我在您所有的示例中看到,您的元组由字符串组成。我知道这只是为了说明方法,但自定义类在将其转换为字符串后反序列化时是否会保留其属性?显然,如果解决了那个问题,这里的两种方法都对我完美地起作用。再次感谢您清晰的解释。 - adwaraki
@adwaraki:如果你的元组不包含字符串而是自定义对象,你需要找到其他序列化和反序列化它们的方法。这超出了本答案的范围。 - Martijn Pieters
我很抱歉。我在问题本身中应该表达得更清楚。我添加了这句话,但应该为了明确起见加粗它。你能指引我去哪个地方吗? - adwaraki
1
@adwaraki:你可以给你的自定义类添加一个__json__方法,将它们转换为可进行JSON序列化的值,并添加一个类方法来再次从JSON中恢复对象,但是将它们存储在元组中会变得更加复杂。 - Martijn Pieters
太棒了。谢谢。我会研究一下,或者找到一个解决方法。感谢您的帮助。您的方法对我使用的另一种序列化方法也有帮助。 :) - adwaraki

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接