首页 > 解决方案 > Python json.loads object_hook=OrderedDict 不工作

问题描述

我有以下 json 文件:

{
  "glossary": {
    "title": "example glossary",
    "GlossaryID": "5302",
    "GlossDiv": {
      "title": "S",
      "GlossList": {
        "GlossEntry": {
          "ID": "SGML",
          "SortAs": "SGML",
          "GlossTerm": "Standard Generalized Markup Language",
          "Acronym": "SGML",
          "Abbrev": "ISO 8879:1986",
          "GlossDef": {
            "para": "A meta-markup language, used to create markup languages such as DocBook.",
            "GlossSeeAlso": [
              "GML",
              "XML"
            ]
          },
          "GlossSee": "markup"
        }
      }
    }
  }
}

我正在使用以下命令读取这个 json 文件:

数据 = json.loads(str,object_hook=OrderedDict)

但是,它仍然不保持插入顺序:

OrderedDict([
  (u'glossary',
  OrderedDict([
    (u'GlossDiv',
    OrderedDict([
      (u'GlossList',
      OrderedDict([
        (u'GlossEntry',
        OrderedDict([
          (u'GlossDef',
          OrderedDict([
            (u'GlossSeeAlso',
            [
              u'GML',
              u'XML'
            ]),
            (u'para',
            u'A meta-markup language, used to create markup languages such as DocBook.')
          ])),
          (u'GlossSee',
          u'markup'),
          (u'Acronym',
          u'SGML'),
          (u'GlossTerm',
          u'Standard Generalized Markup Language'),
          (u'Abbrev',
          u'ISO 8879:1986'),
          (u'SortAs',
          u'SGML'),
          (u'ID',
          u'SGML')
        ]))
      ])),
      (u'title',
      u'S')
    ])),
    (u'GlossaryID',
    u'5302'),
    (u'title',
    u'example glossary')
  ]))
])

我正在遍历字典中的项目并列出根元素及其元素。我希望它的顺序与 json 文件中的顺序相同。

我正在寻找 json 中的结构和数组,每个数组或结构对我来说都是不同的表。所以我希望输出为:

Glossary-
title:example glossary,
GlossaryID:5302

GlossDiv-
title:S

GlossEntry-
ID: SGML,
SortAs: SGML,
GlossTerm: Standard Generalized Markup Language,
Acronym: SGML,
Abbrev: ISO 8879:1986,
GlossSee: markup

等等。但是,因为它没有保持顺序,所以我得到它:

glossary
GlossDiv
GlossList
GlossEntry
GlossDef
GlossSeeAlso
para : A meta-markup language, used to create markup languages such as DocBook.
GlossSee : markup
Acronym : SGML
GlossTerm : Standard Generalized Markup Language
Abbrev : ISO 8879:1986
SortAs : SGML
ID : SGML
title : S
GlossaryID : 5302
title : example glossary

标签: pythonjson

解决方案


当您使用该object_hook参数时,解码器将首先将映射重建为普通 dict,然后将该 dict 传递给给定的钩子。这将失去项目的顺序。

大概你使用的是 3.7 之前的 python 版本(因为 dicts 在 3.7 中默认排序),如果你检查json你的版本的模块文档(例如3.6),你会在object_pairs_hook参数中找到答案:

object_pairs_hook是一个可选函数,将调用使用有序对列表解码的任何对象文字的结果。将使用object_pairs_hook的返回值而不是dict. 此功能可用于实现依赖于键值对解码顺序的自定义解码器(例如,collections.OrderedDict()将记住插入的顺序)。如果还定义了object_hook,则object_pairs_hook优先。

替换object_hookobject_pairs_hook, 这应该可以满足您的要求。


推荐阅读