我可以将 JSON 加载到 OrderedDict 中吗?

发布于 2024-11-27 12:19:14 字数 176 浏览 2 评论 0原文

好的,我可以在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

缪败 2024-12-04 12:19:14

是的,你可以。通过将 object_pairs_hook 参数指定为 JSONDecoder。事实上,这正是文档中给出的示例。

>>> json.JSONDecoder(object_pairs_hook=collections.OrderedDict).decode('{"foo":1, "bar": 2}')
OrderedDict([('foo', 1), ('bar', 2)])
>>> 

您可以将此参数传递给 json.loads (如果您不需要 Decoder 实例用于其他目的),如下所示:

>>> 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)

Yes, you can. By specifying the object_pairs_hook argument to JSONDecoder. In fact, this is the exact example given in the documentation.

>>> json.JSONDecoder(object_pairs_hook=collections.OrderedDict).decode('{"foo":1, "bar": 2}')
OrderedDict([('foo', 1), ('bar', 2)])
>>> 

You can pass this parameter to json.loads (if you don't need a Decoder instance for other purposes) like so:

>>> 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
}
>>> 

Using json.load is done in the same way:

>>> data = json.load(open('config.json'), object_pairs_hook=OrderedDict)
双手揣兜 2024-12-04 12:19:14

Python 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)

Simple version for Python 2.7+

my_ordered_dict = json.loads(json_str, object_pairs_hook=collections.OrderedDict)

Or for Python 2.4 to 2.6

import simplejson as json
import ordereddict

my_ordered_dict = json.loads(json_str, object_pairs_hook=ordereddict.OrderedDict)
空城仅有旧梦在 2024-12-04 12:19:14

一些好消息!从版本 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))

在 py3.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! :)

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:

import json
data = json.loads('{"foo":1, "bar":2, "fiddle":{"bar":2, "foo":1}}')
print(json.dumps(data, indent=4))

In py3.5 the resulting order is undefined:

{
    "fiddle": {
        "bar": 2,
        "foo": 1
    },
    "bar": 2,
    "foo": 1
}

In the cPython implementation of python 3.6:

{
    "foo": 1,
    "bar": 2,
    "fiddle": {
        "bar": 2,
        "foo": 1
    }
}

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! :)

愁杀 2024-12-04 12:19:14

如果指定 object_pairs_hook 参数,通常使用的加载命令将起作用:

import json
from  collections import OrderedDict
with open('foo.json', 'r') as fp:
    metrics_types = json.load(fp, object_pairs_hook=OrderedDict)

The normally used load command will work if you specify the object_pairs_hook parameter:

import json
from  collections import OrderedDict
with open('foo.json', 'r') as fp:
    metrics_types = json.load(fp, object_pairs_hook=OrderedDict)
謸气贵蔟 2024-12-04 12:19:14

除了转储字典之外,您总是可以写出键列表,然后通过迭代列表来重建 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?

一抹苦笑 2024-12-04 12:19:14

除了将有序的键列表与字典一起转储之外,另一个低技术解决方案(其优点是显式)是转储键值对的(有序)列表 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 simple OrderedDict(<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 the object_pairs_hook argument), so an explicit conversion of only the dictionaries that must be ordered makes sense too.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文