使用here描述的方法,我在加载嵌套的JSON文件时将OrderedDict
作为object_pairs_hook
传递,以保留顺序。
保留订单,这对于JSON对象的大多数来说都很好。但是JSON的一部分(在嵌套的最低级别),看起来像:
"In Content" : {
"Sulvo" : "abc.com_336x280_he-inlinecontentmobile",
"Sulvo" : "abc.com_336x280_he-inlinecontentmobile_level2",
"Sulvo" : "abc.com_336x280_he-inlinecontentmobile_level3",
"Adsense" : ""
},
处理后,只保留其中一个相同的键:
OrderedDict([(u'Sulvo', u'homeepiphany.com_336x280_he-inlinecontentmobile_level3'),
(u'Adsense', u'')])),
我知道我们可以拥有一个字典,该字典包含具有defaultdict
的相同键名的多个项目。以下不起作用,即使它确实如此,我认为我们会获得钥匙但却失去了订单,所以我们不会更好:
j = json.load(open('he.json'), object_pairs_hook=defaultdict)
是否可以一次性维护订单 AND 保留所有密钥?
Python 2.7.12
答案 0 :(得分:3)
如果查看docs for json.load
,它们会概述object_pairs_hook
参数的作用:
object_pairs_hook
是一个可选函数,将使用对有序列表对解码的任何对象文字的结果进行调用。将使用object_pairs_hook
的返回值代替dict
。
您需要做的就是编写一个函数,在给定(key, value)
对列表的情况下,构造您的对象。
一种方法是什么也不做,只是直接传递项目列表而不构建字典:
def handle_mapping(items):
return items
然后,你的JSON解析如下:
[(u'In Content',
[(u'Sulvo', u'abc.com_336x280_he-inlinecontentmobile'),
(u'Sulvo', u'abc.com_336x280_he-inlinecontentmobile_level2'),
(u'Sulvo', u'abc.com_336x280_he-inlinecontentmobile_level3'),
(u'Adsense', u'')])]
如果您确实要将重复键的值合并到列表中,可以使用OrderedDict
:
def handle_mapping(items):
d = OrderedDict()
duplicate_keys = set()
for key, value in items:
# So [('k', 'v')] becomes {'k': 'v'}
if key not in d:
d[key] = value
else:
# So [('k', 'v1'), ('k', 'v2')] becomes {'k': ['v1', 'v2']}
if key not in duplicate_keys:
duplicate_keys.add(key)
d[key] = [d[key]]
d[key].append(value)
return d
然后,您将对象解析为:
OrderedDict([(u'In Content',
OrderedDict([(u'Sulvo',
[u'abc.com_336x280_he-inlinecontentmobile',
u'abc.com_336x280_he-inlinecontentmobile_level2',
u'abc.com_336x280_he-inlinecontentmobile_level3']),
(u'Adsense', u'')]))])