从API解析JSON列表/字典

时间:2015-04-27 19:54:56

标签: python json python-3.x python-requests simplejson

我开发了一个小型库,并且有兴趣让用户更容易从返回的JSON列表/字典中检索数据。我创建了使用 requests 处理调用的函数。现在假设我调用此函数并传入一些参数:

precip = precipitation_obs(stid='kfnl', start='201504261800', end='201504271200', units='precip|in')

这将返回以下JSON:

{ 'STATION': [ { 'ELEVATION': '5016',
                 'ID': '192',
                 'LATITUDE': '40.45',
                 'LONGITUDE': '-105.01667',
                 'MNET_ID': '1',
                 'NAME': 'Fort Collins/Loveland, Fort Collins-Loveland '
                         'Municipal Airport',
                 'OBSERVATIONS': { 'count_1': 6,
                                   'ob_end_time_1': '2015-04-27T00:55:00Z',
                                   'ob_start_time_1': '2015-04-26T18:55:00Z',
                                   'total_precip_value_1': 0.13,
                                   'vids case4': ['39', '51', '40', '52']},
                 'STATE': 'CO',
                 'STATUS': 'ACTIVE',
                 'STID': 'KFNL',
                 'TIMEZONE': 'US/Mountain'}],
  'SUMMARY': { 'METADATA_RESPONSE_TIME': '5.22613525391 ms',
               'NUMBER_OF_OBJECTS': 1,
               'RESPONSE_CODE': 1,
               'RESPONSE_MESSAGE': 'OK',
               'TOTAL_TIME': '57.6429367065 ms'}}    

现在,我希望用户能够深入查看字典,但STATION是一个列表,需要我执行以下操作:

output =  precip['STATION'][0]['OBSERVATIONS']['ob_start_time_1'] 
print(output)
# returns 2015-04-26T18:55:00Z

我必须包含[0]以避免:

TypeError: list indices must be integers, not str

这周围有吗?在那里添加[0]确实可以解决问题。或者甚至每次都必须指定['STATION']有点令人讨厌。我应该使用simpleJSON模块来帮助吗?任何提高这一点的技巧都会很棒,谢谢!

1 个答案:

答案 0 :(得分:1)

  

在那里添加[0]确实可以解决问题。或者甚至每次都必须指定['STATION']有点麻烦。

所以只需将precip['STATION'][0]存储在变量中:

>>> precip0 = precip['STATION'][0]

现在,你可以反复使用它:

>>> precip0['OBSERVATIONS']['ob_start_time_1']
2015-04-26T18:55:00Z

如果您知道API总是会返回一个站点,并且您永远不会想要除该站点的数据之外的任何其他内容,您可以将它放在您的包装器函数中:

def precipitation_obs(stid, start, end, units):
    # your existing code, which assigns something to result
    return result['STATION'][0]

如果您在这里担心“效率”,请不要担心。首先,这不是复制任何东西,它只是对已经存在的同一个对象进行另一个引用 - 它需要不到一微秒,并且浪费大约8个字节。实际上,它保存你的内存,因为如果你没有存储整个dict,只是sub-dict,Python可以垃圾收集结构的其余部分。而且,更重要的是,这种微优化不值得担心,直到(1)您的代码正常工作,(2)您知道这是一个瓶颈。

  

我应该使用simpleJSON模块来帮助吗?

为什么你认为这会有所帮助?正如its readme says

  

simplejson是Python 2.6和Python 3.0中包含的json库的外部维护开发版本,但保持与Python 2.5的向后兼容性。

换句话说,它与您在stdlib中已经获得的代码相同,或者是该代码的旧版本。

有时一个不同的库,比如ijson,可以提供帮助 - 例如,如果JSON结构太大,以至于你无法将整个事物解析到内存中,或者如此复杂,在SAX风格中更容易描述你想要颠倒的东西。但这与此无关。