我正在从web api解析JSON,而Python似乎在重复迭代时将这些密钥洗牌。
屏幕截图上的原始JSON(它是正确的原始排序。不,它不是按字母顺序排序):
我的代码:
data = requests.get('http://www.dota2.com/jsfeed/heropediadata?feeds=abilitydata&l=english').json()
for key in data['abilitydata']:
print key
输出:
tiny_avalanche
rubick_fade_bolt
doom_bringer_devour
undying_flesh_golem
...
我也试过通过urllib& json.loads() - 它给出了相同的结果。
如何才能实现原始订购?
答案 0 :(得分:5)
您可以在json包中使用有序字典和loads方法的object_pairs_hook参数。这是一个有效的代码示例:
import json
import requests
from collections import OrderedDict
result = requests.get('http://www.dota2.com/jsfeed/heropediadata?feeds=abilitydata&l=english')
data = json.loads(result.text, object_pairs_hook = OrderedDict)
数据将按顺序包含您的字典键
答案 1 :(得分:3)
正如其他人所说,dict
是无序的。 collections.OrderedDict
是一个dict子类,其键是有序的。问题是json.load
直接返回dict
,我们不能只将结果抛出OrderedDict
,因为此时键的顺序已经丢失了信息。< / p>
我们需要一种方式告诉json.load
返回OrderedDict
而不是dict
。这可以通过实现提供{{1}的自定义json.JSONDecoder
来完成}}。 object_pairs_hook
被赋予一个JSON对象作为object_pairs_hook
元组的列表,按照它们在JSON文档中出现的顺序。它应该返回此对象到Python对象的转换。我们将这个元组列表交给(key, value)
的初始化器,这应该可以解决问题。
以下是一些代码:
collections.OrderedDict
给出:
data = """
{
"foo": "bar",
"a_list": [1, 2, 3],
"another_object": {
"c": 3,
"a": 1,
"b": 2
},
"last_key": 42
}
"""
decoder = json.JSONDecoder(object_pairs_hook=collections.OrderedDict)
result = decoder.decode(data)
print(result)
最后,你可能想知道:“为什么这么多额外的工作呢?”好吧,JSON并不意味着被视为具有任何固定顺序的数据结构。你这样做是违背金钱的。
答案 2 :(得分:1)
因为Python词典是无序的。
解析JSON文本时,会得到一个字典。因为字典类型没有顺序,所以只能以未定义的顺序迭代键。
答案 3 :(得分:1)
dict
类型是Python中的内置类型。这是无序的。
如果您希望能够恢复字典中的键顺序,可以使用OrderedDict
类中的collections
。
见这个例子:
>>> import collections
>>> data = collections.OrderedDict()
>>> data['pear'] = 1
>>> data['apple'] = 3
>>> data['orange'] = 2
>>> data['lemon'] = 4
>>>
>>>
>>> print data
OrderedDict([('pear', 1), ('apple', 3), ('orange', 2), ('lemon', 4)])
>>>
>>>
>>> data2 = dict()
>>> data2['pear'] = 1
>>> data2['apple'] = 3
>>> data2['orange'] = 2
>>> data2['lemon'] = 4
>>>
>>>
>>> print data2
{'orange': 2, 'lemon': 4, 'pear': 1, 'apple': 3}
>>>
有关详情,请参阅:https://docs.python.org/2/library/collections.html#collections.OrderedDict