我有这种格式的json文件,
{
"details": {
"hawk_branch": {
"tandem": {
"value": "4210bnd72"
}
},
"uclif_branch": {
"tandem": {
"value": "e2nc712nma89",
"value": "23s24212",
"value": "12338cm82",
}
}
}
}
问题是,我需要保留所有value
,但是当我使用json.load
加载此文件时,我只能得到一个value
,这自{{1} }只能保留唯一的dict
。
这是预期的输出,
keys
我已经阅读了Python json parser allow duplicate keys的答案,可以像这样使用{ "hawk_branch": ["4210bnd72"] }
{ "uclif_branch": ["e2nc712nma89" , "23s24212", "12338cm82"] }
object_pairs_hook
,但是它返回整个json文件为def parse_object_pairs(pairs):
return pairs
# f is file
json.load(f, object_pairs_hook=parse_object_pairs)
。
我认为可以将list
用作lambda
来做到这一点,但我不知道该如何使用。
有人可以指导我吗
答案 0 :(得分:3)
您可以使用自定义重复键解析器功能,该功能将value
键的值转换为列表:
def value_resolver(pairs):
if all(k == 'value' for k, _ in pairs):
return [v for _, v in pairs]
return dict(pairs)
这样:
json.load(f, object_pairs_hook=value_resolver)
返回:
{'details': {'hawk_branch': {'tandem': ['4210bnd72']}, 'uclif_branch': {'tandem': ['e2nc712nma89', '23s24212', '12338cm82']}}}
要通过将列表转换为具有重复的value
键的字典来将新的数据结构转回原始JSON格式,可以使用自定义的json.JSONEncoder
子类:
class restore_value(json.JSONEncoder):
def encode(self, o):
if isinstance(o, dict):
return '{%s}' % ', '.join(': '.join((json.encoder.py_encode_basestring(k), self.encode(v))) for k, v in o.items())
if isinstance(o, list):
return '{%s}' % ', '.join('"value": %s' % self.encode(v) for v in o)
return super().encode(o)
这样:
d = {'details': {'hawk_branch': {'tandem': ['4210bnd72']}, 'uclif_branch': {'tandem': ['e2nc712nma89', '23s24212', '12338cm82']}}}
print(json.dumps(d, cls=restore_value))
将输出:
{"details": {"hawk_branch": {"tandem": {"value": "4210bnd72"}}, "uclif_branch": {"tandem": {"value": "e2nc712nma89", "value": "23s24212", "value": "12338cm82"}}}}