JSON 键在 Python 中随机排列
JSON keys are shuffled in Python
我正在从网络 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() 来做到这一点——它给出了相同的结果。
怎样才能实现原来的排序?
因为Python 字典是无序的。
当您解析 JSON 文本时,您会得到一本字典。因为字典类型没有顺序,键只能以未定义的顺序迭代。
dict
类型是 Python 中的内置类型。它是无序的。
如果你想恢复字典中键的顺序,你可以使用 collections
class.
中的 OrderedDict
看这个例子:
>>> 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
正如其他人所说,dict
是无序的。 collections.OrderedDict
是一个 dict 子类,其键是有序的。问题是 json.load
return 直接是 dict
,我们不能直接把结果扔进 OrderedDict
,因为键的顺序已经丢失了信息这一点。
我们需要一种方法来告诉 json.load
到 return 一个 OrderedDict
而不是 dict
。这可以通过实现自定义 json.JSONDecoder
来完成它提供了一个 object_pairs_hook
。 object_pairs_hook
被赋予一个 JSON 对象作为 (key, value)
元组的列表,按照它们在 JSON 文档中出现的顺序排列。它应该 return 将此对象翻译成 Python 对象。我们将把这个元组列表传递给 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)
给出:
OrderedDict([('foo', 'bar'),
('a_list', [1, 2, 3]),
('another_object', OrderedDict([('c', 3), ('a', 1), ('b', 2)])),
('last_key', 42)])
最后,您可能想知道:"why is this so much extra work?"。好吧,JSON 并不意味着被视为具有任何固定顺序的数据结构。你这样做是有违常理的。
您可以使用有序字典和 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)
数据将按顺序包含您的字典键
我正在从网络 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() 来做到这一点——它给出了相同的结果。
怎样才能实现原来的排序?
因为Python 字典是无序的。
当您解析 JSON 文本时,您会得到一本字典。因为字典类型没有顺序,键只能以未定义的顺序迭代。
dict
类型是 Python 中的内置类型。它是无序的。
如果你想恢复字典中键的顺序,你可以使用 collections
class.
OrderedDict
看这个例子:
>>> 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
正如其他人所说,dict
是无序的。 collections.OrderedDict
是一个 dict 子类,其键是有序的。问题是 json.load
return 直接是 dict
,我们不能直接把结果扔进 OrderedDict
,因为键的顺序已经丢失了信息这一点。
我们需要一种方法来告诉 json.load
到 return 一个 OrderedDict
而不是 dict
。这可以通过实现自定义 json.JSONDecoder
来完成它提供了一个 object_pairs_hook
。 object_pairs_hook
被赋予一个 JSON 对象作为 (key, value)
元组的列表,按照它们在 JSON 文档中出现的顺序排列。它应该 return 将此对象翻译成 Python 对象。我们将把这个元组列表传递给 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)
给出:
OrderedDict([('foo', 'bar'),
('a_list', [1, 2, 3]),
('another_object', OrderedDict([('c', 3), ('a', 1), ('b', 2)])),
('last_key', 42)])
最后,您可能想知道:"why is this so much extra work?"。好吧,JSON 并不意味着被视为具有任何固定顺序的数据结构。你这样做是有违常理的。
您可以使用有序字典和 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)
数据将按顺序包含您的字典键