是否可以使用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>, {})
答案 0 :(得分:2)
创建递归字典还不够。您必须递归地将JSON对象加载到dict中。
您的代码中发生的事情是ni['a']
是普通字典,而不是nd
类型的字典。当您运行ni.update(d)
时,更新并不足以遍历d
,将每个级别的对象写入相似类型的对象。相反,它只是将d
的第一级值和键复制到ni
。第一级值只是普通的dicts或其他。
要正确初始化ni
,您需要编写一个递归函数来确定每个值是否为dict,数组或标量。如果它是一个字典,则必须调用nd
,然后用相同递归方式处理的值填充结果。
或者,您可以将参数object_hook
用于json.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
或者类似的东西可能会对你有所帮助。