【问题标题】:How to convert dict into recursive defaultdict and load JSON?如何将dict转换为递归defaultdict并加载JSON?
【发布时间】:2018-11-16 17:23:34
【问题描述】:

有什么方法可以使用 Python 2.7 将 JSON 代码加载到递归 defaultdict 中以避免 KeyError

例如:

from __future__ import print_function
from collections import defaultdict
import json

S =  '{"a": [{"b": "TEST1", "p": "TEST2"}, {"b": "TEST3", "p": "TEST4"}]}'

d = json.loads(S)
nd = lambda: defaultdict(nd)
ni = nd()
print('1: ', ni['a'][0]['b'])
ni.update(d)
print('2: ', ni['a'][0]['b'])
print('3: ', ni['a'][1]['p'])
print('4: ', ni['a'][1]['c'])

结果

1:  defaultdict(<function <lambda> at 0x0266F530>, {})
2:  TEST1
3:  TEST4
Traceback (most recent call last):
  File "C:/...", line 16, in <module>
    print('4: ', ni['a'][1]['c'])
KeyError: 'c'

它看起来像 ni.update(d) ni 之后的 dict,而不像递归 defaultdict。有什么方法可以将dict 添加到递归defaultdict 中并保留其属性?

我希望第 4 步的结果类似于以下内容:

4:  defaultdict(<function <lambda> at 0x0266F530>, {})

【问题讨论】:

  • ni['a'][0] 引用与键 'a' 关联的 list 值的第一个元素。 [0] 中的零是一个索引,而不是字典键(因为d 只是一个普通的dict),所以你试图将字典列表的字典与递归的defaultdict 混合。这意味着您需要编写代码将其转换为类似于下面@jwg's answer 中的内容。

标签: python json python-2.7 recursion defaultdict


【解决方案1】:

创建递归字典是不够的。您必须递归地将 JSON 对象加载到您的 dict 中。

在您的代码中发生的情况是 ni['a'] 是一个普通的字典,而不是 nd 类型的字典。当您运行ni.update(d) 时,update 不够聪明,无法遍历d,将每个级别的对象写入类似类型的对象中。相反,它只是将d 的一级值和键复制到ni 中。第一级值只是普通的字典或其他任何东西。

要正确初始化ni,您需要编写一个递归函数来确定每个值是字典、数组还是标量。如果它是一个 dict,它必须调用 nd,然后用它将以相同的递归方式作用的值填充结果。

或者,您可以使用参数object_hookjson.loads。有关详细信息,请参阅https://docs.python.org/2/library/json.html#json.load。无论您在此处传递什么函数,都将在任何解析级别创建的每个 dict 上调用。所以函数

def defaultdict_from_dict(d):
    nd = lambda: defaultdict(nd)
    ni = nd()
    ni.update(d)
    return ni

或类似的东西可能会为您解决问题。

【讨论】:

    猜你喜欢
    • 2013-12-24
    • 1970-01-01
    • 2014-12-17
    • 1970-01-01
    • 2019-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-13
    相关资源
    最近更新 更多