将字典转换为JSON时保持顺序

9

我想将数据库查询结果序列化为JSON。每行有若干列,我把它们添加到一个字典中。这些列有一定的顺序,但在序列化数据时,顺序会发生改变。我尝试使用 OrderedDict,但仍然遇到了同样的问题。如何保持列的顺序?

res = {'a': i[0], 'b': i[1], 'c': i[2]}
return jsonify(res=res)

res = OrderedDict()
res['a'] = i[0]
res['b'] = i[1]
res['c'] = i[3]
return jsonify(res=res)

6
字典不保证顺序。你可以尝试使用“OrderedDict”,但我不知道“jsonify”会如何处理它——如果顺序很重要,最好使用有序数据结构。 - jonrsharpe
2个回答

6
Python字典和JSON对象没有顺序,因此没有直接的方法来实现这一点。在Python中,OrderedDict维护插入顺序,但是在JSON中没有等效物。您可以将字典转换为其项目的列表,因为列表是有序的。
data = OrderedDict()
data['a'] = 1
data['b'] = 2
jsonify(data=list(data.items()))

如果您需要知道这个特定列表实际上是一个有序字典,您可以使用标记方案来标记每个值的类型。这会变得更加复杂。您可以在Flask的会话序列化器中找到一个示例。

3

使用Flask的jsonify()无法实现,但是可以使用普通的json.dumps()。唯一需要注意的是,由于响应头中设置了内容长度,因此必须使内容长度匹配:

import json
from collections import OrderedDict
from flask import Flask, jsonify
app = Flask(__name__)

@app.route("/unordered")
def unordered_dict():
    d = OrderedDict([('e',1),('d',2),('c',3),('b',4),('a',5)])
    output = jsonify(d)
    return output

@app.route("/ordered")
def ordered_dict():
    d = OrderedDict([('e',1),('d',2),('c',3),('b',4),('a',5)])
    response = json.dumps(d)
    placeholder = '_'*(len(response)-2) # Create a placeholder, -2 due to ""
    output = jsonify(placeholder) # This needs to be the same length as the response
    output.response[0] = response + '\n' # Replace with the actual response
    return output

第一个默认按字母顺序返回,或者如果app.config['JSON_SORT_KEYS'] = False则返回随机顺序。第二个应该按指定的顺序返回键。
注意:正如其他人所指出的那样,JSON规范不要求顺序。然而,大多数浏览器似乎仍然尊重顺序,因此在需要但不是必要的情况下可以使用它。如果顺序很重要,则您唯一的选择是在转换为JSON之前将其转换为列表。
(注:在https://github.com/pallets/flask/issues/1877之前,Content-Length没有明确设置,因此它要简单得多!)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接