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

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (18)

我正在使用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 - 但是我有时区,id,名字。

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

提问于
用户回答回答于

Python dict(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}'

如果需要特定的订单; 你可以使用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 - 保留关键字参数顺序

如果你的输入给出JSON然后保存顺序(得到OrderedDict),你可以传递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,但我不确定(并且我没有简单的测试方法)。

老pythons simplejson实现不会很好地处理OrderedDict对象..并在输出它们之前将它们转换为常规的dicts ..但是可以通过执行以下操作来克服此问题:

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

这非常符合要求。

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

扫码关注云+社区