好的,我可以在json.dump
中使用OrderedDict。也就是说,OrderedDict可以作为JSON的输入。
但是它能用作输出吗?如果可以,怎么做?在我的情况下,我想要load
到一个OrderedDict中,以便保留文件中键的顺序。
如果不行,有没有什么解决办法?
好的,我可以在json.dump
中使用OrderedDict。也就是说,OrderedDict可以作为JSON的输入。
但是它能用作输出吗?如果可以,怎么做?在我的情况下,我想要load
到一个OrderedDict中,以便保留文件中键的顺序。
如果不行,有没有什么解决办法?
可以的,你可以通过在JSONDecoder中指定object_pairs_hook
参数来实现。事实上,这正是官方文档中提供的示例。
>>> json.JSONDecoder(object_pairs_hook=collections.OrderedDict).decode('{"foo":1, "bar": 2}')
OrderedDict([('foo', 1), ('bar', 2)])
>>>
如果您没有其他用途需要 Decoder 实例,可以将此参数传递给 json.loads
,如下所示:
>>> import json
>>> from collections import OrderedDict
>>> data = json.loads('{"foo":1, "bar": 2}', object_pairs_hook=OrderedDict)
>>> print json.dumps(data, indent=4)
{
"foo": 1,
"bar": 2
}
>>>
使用 json.load
的方式与此相同:
>>> data = json.load(open('config.json'), object_pairs_hook=OrderedDict)
object_pairs_hook
,而不是“每个配对都将传递给object_pairs_hook
”。 - SingleNegationEliminationOrderedDict
来构建生成的 Python 值。 - SingleNegationEliminationPython 2.7+ 的简化版本。
my_ordered_dict = json.loads(json_str, object_pairs_hook=collections.OrderedDict)
或针对 Python 2.4 到 2.6
import simplejson as json
import ordereddict
my_ordered_dict = json.loads(json_str, object_pairs_hook=ordereddict.OrderedDict)
好消息!自3.6版本起,cPython实现已经保留了字典的插入顺序(https://mail.python.org/pipermail/python-dev/2016-September/146327.html)。这意味着json库现在默认情况下是有序的。观察Python 3.5和3.6之间的行为差异。代码:
import json
data = json.loads('{"foo":1, "bar":2, "fiddle":{"bar":2, "foo":1}}')
print(json.dumps(data, indent=4))
在Python 3.5中,结果的顺序是未定义的:
{
"fiddle": {
"bar": 2,
"foo": 1
},
"bar": 2,
"foo": 1
}
在 Python 3.6 的 cPython 实现中:
{
"foo": 1,
"bar": 2,
"fiddle": {
"bar": 2,
"foo": 1
}
}
非常好的消息是,自Python 3.7以来,这已成为语言规范(而不是cPython 3.6+的实现细节):https://mail.python.org/pipermail/python-dev/2017-December/151283.html
因此,现在回答您的问题就变成了:升级到Python 3.6!:)
json.loads('{"2": 2, "1": 1}')
对我来说变成了{'1': 1, '2': 2}
。 - fuglededict.__repr__
会对键进行排序,但底层的顺序仍保持不变。换句话说,即使repr(json.loads('{"2": 2, "1": 1}'))
的结果是"{'1': 1, '2': 2}"
,json.loads('{"2": 2, "1": 1}').items()
返回的结果仍然是dict_items([('2', 2), ('1', 1)])
。 - Simon Charettedict.__repr__
-在任何Python版本中都不会进行排序。) - user2357112除了转储字典之外,您还可以编写键列表,并通过迭代该列表来重构OrderedDict
?
OrdereDict
递归完成。 - martineauimport json
from collections import OrderedDict
with open('foo.json', 'r') as fp:
metrics_types = json.load(fp, object_pairs_hook=OrderedDict)
ordered_dict.items()
;加载则是简单的OrderedDict(<list of key-value pairs>)
。这处理了有序字典,尽管JSON没有这个概念(JSON字典没有顺序)。json
以正确顺序转储OrderedDict确实很好。然而,通常情况下,通过object_pairs_hook
参数将所有JSON字典都读取为OrderedDict(即使不需要),可能会使得负担过重且意义不明确,因此只对必须有序的字典进行显式转换也是有意义的。
json.load
中有一个简单的勾选框可以使用OrderedDicts而不是Dicts,那将是很棒的。 - c00kiemonster