我可以将 JSON 加载到 OrderedDict 中吗?
好的,我可以在 json.dump 中使用 OrderedDict。也就是说,OrderedDict 可以用作 JSON 的输入。
但它可以用作输出吗?如果是这样怎么办?就我而言,我想加载
到OrderedDict中,这样我就可以保持文件中键的顺序。
如果没有,是否有某种解决方法?
Ok so I can use an OrderedDict in json.dump
. That is, an OrderedDict can be used as an input to JSON.
But can it be used as an output? If so how? In my case I'd like to load
into an OrderedDict so I can keep the order of the keys in the file.
If not, is there some kind of workaround?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
是的,你可以。通过将
object_pairs_hook
参数指定为 JSONDecoder。事实上,这正是文档中给出的示例。您可以将此参数传递给
json.loads
(如果您不需要 Decoder 实例用于其他目的),如下所示:使用
json.load
的方式相同:Yes, you can. By specifying the
object_pairs_hook
argument to JSONDecoder. In fact, this is the exact example given in the documentation.You can pass this parameter to
json.loads
(if you don't need a Decoder instance for other purposes) like so:Using
json.load
is done in the same way:Python 2.7+
或 Python 2.4 至 2.6 的简单版本
Simple version for Python 2.7+
Or for Python 2.4 to 2.6
一些好消息!从版本 3.6 开始,cPython 实现保留了字典的插入顺序 (https ://mail.python.org/pipermail/python-dev/2016-September/146327.html)。这意味着 json 库现在默认保持顺序。观察 python 3.5 和 3.6 之间的行为差异。代码:
在 py3.5 中,结果顺序未定义:
在 python 3.6 的 cPython 实现中:
真正好的消息是,这已成为 python 3.7 的语言规范(而不是 cPython 3.6+ 的实现细节): https://mail.python.org/pipermail/python-dev/2017-December/151283.html
所以你的问题的答案现在变成:升级到python 3.6! :)
Some great news! Since version 3.6 the cPython implementation has preserved the insertion order of dictionaries (https://mail.python.org/pipermail/python-dev/2016-September/146327.html). This means that the json library is now order preserving by default. Observe the difference in behaviour between python 3.5 and 3.6. The code:
In py3.5 the resulting order is undefined:
In the cPython implementation of python 3.6:
The really great news is that this has become a language specification as of python 3.7 (as opposed to an implementation detail of cPython 3.6+): https://mail.python.org/pipermail/python-dev/2017-December/151283.html
So the answer to your question now becomes: upgrade to python 3.6! :)
如果指定 object_pairs_hook 参数,通常使用的加载命令将起作用:
The normally used load command will work if you specify the object_pairs_hook parameter:
除了转储字典之外,您总是可以写出键列表,然后通过迭代列表来重建
OrderedDict
?You could always write out the list of keys in addition to dumping the dict, and then reconstruct the
OrderedDict
by iterating through the list?除了将有序的键列表与字典一起转储之外,另一个低技术解决方案(其优点是显式)是转储键值对的(有序)列表
ordered_dict.items();加载是一个简单的
OrderedDict(<键值对列表>)
。尽管 JSON 没有这个概念(JSON 字典没有顺序),但这会处理有序字典。利用
json
以正确的顺序转储 OrderedDict 的事实确实很好。但是,通常必须将所有 JSON 字典作为 OrderedDict 读取(通过object_pairs_hook
参数),这通常是不必要的繁重,并且不一定有意义,因此显式转换 >只有必须订购的词典才有意义。In addition to dumping the ordered list of keys alongside the dictionary, another low-tech solution, which has the advantage of being explicit, is to dump the (ordered) list of key-value pairs
ordered_dict.items()
; loading is a simpleOrderedDict(<list of key-value pairs>)
. This handles an ordered dictionary despite the fact that JSON does not have this concept (JSON dictionaries have no order).It is indeed nice to take advantage of the fact that
json
dumps the OrderedDict in the correct order. However, it is in general unnecessarily heavy and not necessarily meaningful to have to read all JSON dictionaries as an OrderedDict (through theobject_pairs_hook
argument), so an explicit conversion of only the dictionaries that must be ordered makes sense too.