Vla*_*pov 2 python recursion json python-2.7 defaultdict
有什么方法可以使用 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'])
Run Code Online (Sandbox Code Playgroud)
结果
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'])
Run Code Online (Sandbox Code Playgroud)
它看起来像 afterni.update(d) ni一样工作dict,而不是递归defaultdict。有什么方法可以添加dict到递归中defaultdict并保留其属性吗?
我期望第 4 步的结果类似于以下内容:
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'
Run Code Online (Sandbox Code Playgroud)
创建递归字典是不够的。您必须递归地将 JSON 对象加载到您的字典中。
您的代码中发生的情况是,这ni['a']是一个普通的字典,而不是类型的字典nd。当您运行时ni.update(d), update 不够聪明,无法遍历d,将每个级别上的对象写入类似类型的对象。相反,它只是将第一级值和键复制d到 中ni。第一级值只是普通的字典或其他什么。
为了正确初始化ni,您需要编写一个递归函数来确定每个值是字典、数组还是标量。如果它是一个字典,它必须调用nd,然后用将以相同递归方式操作的值填充结果。
或者,您可以使用object_hook的参数json.loads。有关详细信息,请参阅https://docs.python.org/2/library/json.html#json.load。无论您在此处传递什么函数,都将在任何解析级别创建的每个字典上调用。所以函数
def defaultdict_from_dict(d):
nd = lambda: defaultdict(nd)
ni = nd()
ni.update(d)
return ni
Run Code Online (Sandbox Code Playgroud)
或者类似的东西可能会对你有用。