【问题标题】:Key order while writing a JSON object in Python [duplicate]在 Python 中编写 JSON 对象时的键顺序 [重复]
【发布时间】:2019-06-01 17:35:09
【问题描述】:

作为 web 服务调用的结果,我需要显示如下输出

{
  "predictions": [
    {
      "id": 18009,
      "cuisine": "italian",
      "probability": 0.17846838753494407
    },
    {
      "id": 28583,
      "cuisine": "italian",
      "probability": 0.1918703125538735
    }
  ]
}

我有以下代码来创建对象:

    json_data = []
    for i in range (0, len(predicted_labels)):
        data = {}
        data['id'] = int(test['id'][i])
        data['cuisine'] = categoricalTransformer[predicted_labels[i]]
        item = predicted_probability[i]
        data['probability'] = item[predicted_labels[i]]
        json_data.append(data)
    json_return = {"predictions":json_data}
    return jsonify(json_return)

它按字母顺序重新排序键,如下所示。

{
  "predictions": [
    {
      "cuisine": "italian",
      "id": 18009,
      "probability": 0.17846838753494407
    },
    {
      "cuisine": "italian",
      "id": 28583,
      "probability": 0.1918703125538735
    }
  ]
}

我该怎么办?

【问题讨论】:

  • Json 对象中没有键顺序。
  • 为什么关键顺序是相关的?

标签: python json


【解决方案1】:

您可以查看Ordered Dictionary。它会记住插入顺序,并且您可以通过这种方式通过此集合来组织您的 json。

例子:

datadict = {'a':'a', 'c':'c', 'b':'b'}
import collections

print (collections.OrderedDict(datadict))
#OrderedDict([('a':'a'), ('c':'c'), ('b':'b')])

x = collections.OrderedDict(datadict)
print (dict(x))
#{'a':'a', 'c':'c', 'b':'b'}

print (x == datadict)
#True


print (collections.OrderedDict(sorted(datadict.items(), key=lambda t:t[0])))
#OrderedDict([('a':'a'), ('b':'b'), ('c':'c')])

z = collections.OrderedDict(sorted(datadict.items(), key=lambda t:t[0]))
print (dict(z))
#{'a':'a', 'b':'b', 'c':'c'}

print (z == datadict)
#True

使用它,您可以将json_return dict 对象转换为具有所需插入顺序的OrderedDict,然后返回该OrderedDict 对象或将其转换回dict 并返回该dict

【讨论】:

    【解决方案2】:

    使用collections.defaultdict() 重建您的新字典,并使用collections.OrderedDict() 附加有序字典:

    from collections import OrderedDict
    from collections import defaultdict
    from json import dumps
    
    data = {
        "predictions": [
            {"id": 18009, "cuisine": "italian", "probability": 0.17846838753494407},
            {"id": 28583, "cuisine": "italian", "probability": 0.1918703125538735},
        ]
    }
    
    key_order = ["id", "cuisine", "probability"]
    
    result = defaultdict(list)
    for dic in data["predictions"]:
        ordered = OrderedDict((key, dic.get(key)) for key in key_order)
        result["predictions"].append(ordered)
    
    print(dumps(result))
    # {"predictions": [{"id": 18009, "cuisine": "italian", "probability": 0.17846838753494407}, {"id": 28583, "cuisine": "italian", "probability": 0.1918703125538735}]}
    

    json.dumps() 这里将字典序列化为 JSON 格式的字符串。

    注意:如果您使用的是Python3.6+,您可以使用普通字典代替OrderedDict(),因为会记住键的插入顺序。然而,在 3.6 中它是一个实现特性,而在 3.7 中它是一个语言特性。您可以在Are dictionaries ordered in Python 3.6+? 阅读更多相关信息。

    对于最低要求为 Python3.6 的应用程序,您可能可以依赖此功能。此外,无论如何,它对用户OrderedDict() 可能更安全,因此您的代码可以向后兼容所有 python 版本。

    【讨论】:

    • 虽然 Python 3.6+ 记得插入顺序是正确的,但这种行为是实现更改的副作用,不应依赖。要获得更多面向未来的代码和更高的可重用性,应使用OrderedDict
    • @Grismar 是的,这是一个非常好的观点,干杯。
    • @Grismar 这仅适用于 3.6。从 Python 3.7 开始,它是一个文档化的特性。仍应考虑向后兼容性。
    猜你喜欢
    • 1970-01-01
    • 2018-10-30
    • 2021-11-26
    • 2018-07-28
    • 2015-11-13
    • 1970-01-01
    • 2015-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多