Items in JSON object are out of order using “json.dumps”?
我正在使用
1 2 | countries.append({"id":row.id,"name":row.name,"timezone":row.timezone}) print json.dumps(countries) |
我得到的结果是:
1 2 3 4 5 6 | [ {"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,名称,时区-但是我有timezone,id,名称。
我该如何解决?
Python
1 2 3 4 5 | >>> 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}' |
如果您需要特定的订单;您可以使用
1 2 3 4 5 | >>> 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开始,关键字参数顺序得以保留,并且可以使用更好的语法重写以上内容:
1 2 3 4 | >>> json.dumps(OrderedDict(a=1, b=2)) '{"a": 1,"b": 2}' >>> json.dumps(OrderedDict(b=2, a=1)) '{"b": 2,"a": 1}' |
请参阅PEP 468 –保留关键字参数顺序。
如果您的输入是以JSON形式提供的,则为了保留顺序(获取
1 2 3 4 | >>> 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/)。
我相信较新的pythons json实现可以正确处理内置的OrderedDicts,但是我不确定(而且我无法轻松访问测试)。
旧的python simplejson实现无法很好地处理OrderedDict对象..并在输出它们之前将它们转换为常规dict ..但您可以通过执行以下操作来克服这一点:
1 2 3 4 5 6 | 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) |
现在使用这个我们得到:
1 2 3 4 5 6 7 8 | >>> 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"} |
这几乎是所需要的。
另一种选择是专门使编码器直接使用您的行类,这样就不需要任何中间dict或UnorderedDict。
字典的顺序与其定义的顺序没有任何关系。这对所有字典都是正确的,不仅是那些变成JSON的字典。
1 2 | >>> {"b": 1,"a": 2} {'a': 2, 'b': 1} |
实际上,该字典在到达
1 2 | >>> {"id":1,"name":"David","timezone":3} {'timezone': 3, 'id': 1, 'name': 'David'} |
在JSON中(就像在Javascript中一样),对象键的顺序是没有意义的,因此,它们按什么顺序显示实际上并不重要,它是同一对象。
嘿,我知道这个答案太晚了,但是添加sort_keys并为它赋false,如下所示:
1 | json.dumps({'****': ***},sort_keys=False) |
这对我有用
json.dump()将保留字典的序号。在文本编辑器中打开文件,您将看到。无论您是否发送OrderedDict,它都会保留订单。
但是json.load()会丢失已保存对象的顺序,除非您告诉它加载到OrderedDict()中,这是通过上述J.F.Sebastian的object_pairs_hook参数完成的。
否则它将丢失顺序,因为在通常的操作下,它将保存的字典对象加载到常规字典中,而常规字典不保留给出的项目的价格。