json.dumps搞砸了秩序

时间:2015-05-10 14:41:00

标签: python json

我正在使用json module创建一个包含类似条目的json文件

json.dumps({"fields": { "name": "%s", "city": "%s", "status": "%s", "country": "%s" }})

但是,在创建的json文件中,字段的顺序错误

{"fields": {"status": "%s", "city": "%s", "name": "%s", "country": "%s"}}

这是一个问题,因为%s - 字符串的子目录现在不正确。

如何强制dumps函数保留给定的顺序?

5 个答案:

答案 0 :(得分:27)

正如其他答案正确陈述一样,在Python 3.6之前,词典无序

那就是JSON is also supposed to have unordered mappings,所以原则上将有序词典存储在JSON中没有多大意义。具体地说,这意味着在读取JSON对象时,返回的键的顺序可以是任意的。

在JSON中保留映射顺序(如Python OrderedDict)的好方法是输出一个(键,值)对的数组,在读取时转换回有序映射:

>>> from collections import OrderedDict
>>> import json
>>> d = OrderedDict([(1, 10), (2, 20)])                                         
>>> print d[2]
20
>>> json_format = json.dumps(d.items())                   
>>> print json_format  # Order maintained
[[1, 10], [2, 20]]
>>> OrderedDict(json.loads(json_format))  # Reading from JSON: works!
OrderedDict([(1, 10), (2, 20)])
>>> _[2]  # This works!
20

(注意有序字典是从(键,值)对的列表构造的方式:OrderedDict({1: 10, 2: 20})不起作用:它的键不一定按照字典文字中的顺序排序,因为文字创建了一个Python字典,其键是无序的。)

PS :从Python 3.1开始,json模块offers a hook用于自动将对列表(如上所述)转换为其他类似OrderedDict的内容。

答案 1 :(得分:20)

在创建json对象以记住插入顺序时,您可以选择使用OrderedDict而不是普通dict

>>> from collections import OrderedDict
>>> a = '{"fields": { "name": "%s", "city": "%s", "status": "%s", "country": "%s" }}'
>>> b = json.loads(a, object_pairs_hook=OrderedDict)
>>> json.dumps(b)
'{"fields": {"name": "%s", "city": "%s", "status": "%s", "country": "%s"}}'

答案 2 :(得分:13)

这是一本字典,字典不保持秩序。 您可以改为使用OrderedDict

您还可以添加sort_keys = False参数:

json.dumps(values, sort_keys=False)

答案 3 :(得分:2)

您无法从dict创建OrderedDict,因为在您创建词典时,订单已经更改。所以最好的方法是使用元组创建OrderedDict

from collections import OrderedDict
import json

a = (("name","foo"),("city","bar"),("status","baz"),("country","my"))

b = OrderedDict(a)

c = {"fileds": b}

print json.dumps(c)
Output:
{"fileds": {"name": "foo", "city": "bar", "status": "baz", "country": "my"}}

答案 4 :(得分:2)

Python 3.6.1:

Python 3.6.1 (default, Oct 10 2020, 20:16:48)
[GCC 7.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

>>> import json
>>> json.dumps({'b': 1, 'a': 2})
'{"b": 1, "a": 2}'

Python 2.7.5:

Python 2.7.5 (default, Nov 20 2015, 02:00:19) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.

>>> import json
>>> json.dumps({'b': 1, 'a': 2})
'{"a": 2, "b": 1}'