JSON对象中的项目使用“json.dumps”失序?

我正在使用json.dumps转换成json

 countries.append({"id":row.id,"name":row.name,"timezone":row.timezone}) print json.dumps(countries) 

我得到的结果是:

 [ {"timezone": 4, "id": 1, "name": "Mauritius"}, {"timezone": 2, "id": 2, "name": "France"}, {"timezone": 1, "id": 3, "name": "England"}, {"timezone": -4, "id": 4, "name": "USA"} ] 

我想有以下顺序的键:id,名称,时区 – 而是我有时区,id,名称。

我应该如何解决这个问题?

Python dict和JSON对象都是无序集合。 您可以传递sort_keys参数来对键进行sorting:

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

如果您需要特定的订单 你可以使用collections.OrderedDict

 >>> from collections import OrderedDict >>> json.dumps(OrderedDict([("a", 1), ("b", 2)])) '{"a": 1, "b": 2}' >>> json.dumps(OrderedDict([("b", 2), ("a", 1)])) '{"b": 2, "a": 1}' 

自Python 3.6以来 ,关键字参数顺序被保留,上面的内容可以用更好的语法重写:

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

参见PEP 468 – 保留关键字参数顺序 。

如果你的input是以JSONforms给出的,那么为了保存命令(得到OrderedDict ),你可以按照@Fred Yankowski的build议传递object_pair_hook

 >>> json.loads('{"a": 1, "b": 2}', object_pairs_hook=OrderedDict) OrderedDict([('a', 1), ('b', 2)]) >>> json.loads('{"b": 2, "a": 1}', object_pairs_hook=OrderedDict) OrderedDict([('b', 2), ('a', 1)]) 

正如其他人所说,潜在的字典是无序的。 但是在Python中有OrderedDict对象。 (他们内置在最近的python,或者你可以使用这个: http : //code.activestate.com/recipes/576693/ )。

我相信,新的python的json实现正确地处理内置OrderedDicts,但我不知道(我没有方便的testing)。

老pythons simplejson实现不处理OrderedDict对象很好..并将它们转换为常规词典之前输出它们..但你可以通过执行以下操作来克服这一点:

 class OrderedJsonEncoder( simplejson.JSONEncoder ): def encode(self,o): if isinstance(o,OrderedDict.OrderedDict): return "{" + ",".join( [ self.encode(k)+":"+self.encode(v) for (k,v) in o.iteritems() ] ) + "}" else: return simplejson.JSONEncoder.encode(self, o) 

现在使用这个我们得到:

 >>> import OrderedDict >>> unordered={"id":123,"name":"a_name","timezone":"tz"} >>> ordered = OrderedDict.OrderedDict( [("id",123), ("name","a_name"), ("timezone","tz")] ) >>> e = OrderedJsonEncoder() >>> print e.encode( unordered ) {"timezone": "tz", "id": 123, "name": "a_name"} >>> print e.encode( ordered ) {"id":123,"name":"a_name","timezone":"tz"} 

这是非常想要的。

另一种select是专门编码器直接使用你的行类,然后你不需要任何中间字典或UnorderedDict。

字典的顺序与其定义的顺序没有任何关系。所有字典都是如此,而不仅仅是那些变成JSON的字典。

 >>> {"b": 1, "a": 2} {'a': 2, 'b': 1} 

事实上,字典在翻到json.dumps之前就变成了“颠倒”

 >>> {"id":1,"name":"David","timezone":3} {'timezone': 3, 'id': 1, 'name': 'David'} 

在JSON中,如在Javascript中,对象键的顺序是没有意义的,所以它们显示顺序真的没什么关系,它是同一个对象。

json.dump()将保留你的字典。 在文本编辑器中打开文件,你会看到。 无论您是否发送OrderedDict,它都会保留顺序。

但是json.load()会失去已保存对象的顺序,除非您通过上面指示的JFSebastian指示将其加载到OrderedDict()中,该对象由object_pairs_hook参数完成。

否则会失去顺序,因为在通常的操作下,它会将保存的字典对象加载到一个普通的字典中,而一个普通的字典不会保存它所给出的项目。