使用 "json.dumps" 的 JSON 对象中的项目是否失序?

2024-05-19 18:49:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用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,name,timezone-但是我有timezone,id,name。

我该怎么解决?


Tags: nameidjson顺序密钥countriesrowprint
3条回答

正如其他人所提到的,根本的格言是无序的。然而,python中有OrderedDict对象。(它们是在最近的Python中构建的,或者您可以使用这个:http://code.activestate.com/recipes/576693/)。

我相信较新的pythons json实现正确地处理了内置的OrderedDicts,但我不确定(而且我也不容易进行测试)。

旧的pythons simplejson实现不能很好地处理orderedict对象。。在输出之前把它们转换成规则的指令。。但您可以通过执行以下操作来克服此问题:

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"}

这是非常理想的。

另一种选择是专门化编码器,直接使用row类,然后就不需要任何中间dict或无序的dict了。

Pythondict(在Python 3.7之前)和JSON对象都是无序集合。您可以通过sort_keys参数对键进行排序:

>>> 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}'

如果您需要特定的顺序,您可以use ^{}

>>> 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}'

Since 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 – Preserving Keyword Argument Order

如果输入是JSON,那么为了保持顺序(获得OrderedDict),可以传递object_pair_hookas suggested by @Fred Yankowski

>>> 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)])

字典的顺序与定义它的顺序没有任何关系。所有字典都是这样,而不仅仅是那些转换成JSON的字典。

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

事实上,字典在到达json.dumps之前就被“颠倒”了:

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

相关问题 更多 >