Python json.loads object_hook = OrderedDict不起作用

时间:2018-12-18 13:12:55

标签: python json

我有以下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文件:

data = 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

2 个答案:

答案 0 :(得分:2)

当您使用object_hook参数时,解码器将首先将映射重构为纯字典,然后将该字典传递给给定的挂钩。这将丢失项目的顺序。

大概您正在使用3.7之前的python版本(因为dict在3.7中成为默认命令),并且如果您查看json模块文档中的版本(例如3.6),您将在object_pairs_hook参数中找到答案:

  

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

object_hook替换为object_pairs_hook,这应该可以满足您的需求。

答案 1 :(得分:1)

根据文档:

  

object_hook是一个可选函数,它将被解码的任何对象常量(字典)的结果调用。将使用object_hook的返回值代替dict。

如您所知-这种转换发生在load函数的末尾,这意味着输出不会被“排序”,因为它从dict接收到load整个。 OrderedDict仅在被宣布为“已订购”后才保留输入到OrderedDict的键和值的顺序。

因此,该钩子基本上可以正常工作-但没有您期望的那样。 :)