我正在试图弄清楚如何在Python中查询JSON数组。有人可以告诉我如何通过一个相当复杂的数组进行简单的搜索和打印吗?
我正在使用的示例是:http://eu.battle.net/api/wow/realm/status
我希望看到,例如,如何找到'Silvermoon'服务器,并打印出'人口',然后是'Wintergrasp'阵列中的'控制派'。
目前,数组代码段如下所示:
{"type":"pve","population":"high","queue":false,"wintergrasp":{"area":1,"controlling-faction":0,"status":0,"next":1382350068792},"tol-barad":{"area":21,"controlling-faction":0,"status":0,"next":1382349141932},"status":true,"name":"Silvermoon","slug":"silvermoon","battlegroup":"Cyclone / Wirbelsturm","locale":"en_GB","timezone":"Europe/Paris"}
目前我可以访问主阵列,但似乎无法访问子阵列而不将整个事件复制到另一个似乎很浪费的新变量。我希望能够做一些像
这样的事情import urllib2
import json
req = urllib2.Request("http://eu.battle.net/api/wow/realm/status", None, {})
opener = urllib2.build_opener()
f = opener.open(req)
x = json.load(f) # open the file and read into a variable
# search and find the Silvermoon server
silvermoon_array = ????
# print the population
print silvermoon_array.????
# access the Wintergrasp sub-array
wintergrasp_sub = ????
print wintergrasp_sub.???? # print the controlling-faction variable
这确实可以帮助我掌握如何访问其他内容。
答案 0 :(得分:8)
Python的interactive mode是逐步探索结构化数据的好方法。很容易找到如何访问银月服务器数据:
>>> data=json.load(urllib2.urlopen("http://eu.battle.net/api/wow/realm/status"))
>>> type(data)
<type 'dict'>
>>> data.keys()
[u'realms']
>>> type(data['realms'])
<type 'list'>
>>> type(data['realms'][0])
<type 'dict'>
>>> data['realms'][0].keys()
[u'status', u'wintergrasp', u'battlegroup', u'name', u'tol-barad', u'locale', u'queue', u'timezone', u'type', u'slug', u'population']
>>> data['realms'][0]['name']
u'Aegwynn'
>>> [realm['name'] for realm in data['realms']].index('Silvermoon')
212
>>> silvermoon= data['realms'][212]
>>> silvermoon['population']
u'high'
>>> type(silvermoon['wintergrasp'])
<type 'dict'>
>>> silvermoon['wintergrasp'].keys()
[u'status', u'next', u'controlling-faction', u'area']
>>> silvermoon['wintergrasp']['controlling-faction']
>>> silvermoon['population']
u'high'
如果您还不了解它们,请阅读dictionary.keys,list.index和list comprehensions以了解正在发生的事情。
在弄清楚数据的结构之后,你最终可以重写数据访问,使其更具可读性和效率:
realms= data['realms']
realm_from_name= dict( [(realm['name'], realm) for realm in realms])
print realm_from_name['Silvermoon']['population']
print realm_from_name['Silvermoon']['wintergrasp']['controlling-faction']
至于将数组复制到另一个浪费的变量,你应该知道python传递了值by reference。这意味着当您为新变量分配内容时不会涉及复制。 Here's a simple explanation of passing by value vs passing by reference
最后,你似乎过分担心表现。 Python的哲学是get it right first, optimize later。 当你正常工作时如果你需要更好的性能,那么优化它,如果值得的话。
答案 1 :(得分:1)
这样做你想要的:
# -*- coding: utf-8 -*-
import json
import urllib2
def searchListOfDicts(listOfDicts, attr, value):
"""
Loops through a list of dictionaries and returns matching attribute value pair
You can also pass it slug, silvermoon or type, pve
returns a list containing all matching dictionaries
"""
matches = [record for record in listOfDicts if attr in record and record[attr] == value]
return matches
def myjsonDict():
"""
Opens url, grabs json and puts it inside a dictionary
"""
req = urllib2.Request("http://eu.battle.net/api/wow/realm/status", None, {})
opener = urllib2.build_opener()
f = opener.open(req)
json_dict = json.load(f)
return json_dict
jsonDict = myjsonDict()
#we want to search inside realms list
silverMoonServers = searchListOfDicts(jsonDict["realms"], "name", "Silvermoon")
#access first dictionary that matched "name, Silvermoon" query
print silverMoonServers[0]
print silverMoonServers[0]["wintergrasp"]
print silverMoonServers[0]["wintergrasp"]["controlling-faction"]
答案 2 :(得分:0)
在Python中,json.loads
将json对象映射到python词典,将Arrays
映射到list
,因此进行进一步的操作就像使用常规python dict
和{{1}一样结构。
您可以使用requests和list
lamdbas