2015-04-27 103 views
0

我已經開發了一個小型庫,並有興趣使用戶更容易從返回的JSON列表/字典中檢索數據。我創建了使用請求來處理呼叫的函數。現在假設我調用這個函數,並傳遞一些參數:JSON列表/字典解析從API

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

現在,我希望用戶能夠只通過字典向下鑽取,但站是一個列表,並要求我做到以下幾點:

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

如果這是您的API,爲什麼不簡化輸出呢?是否只有一個站,然​​後不使用列表。如果訪問站點元素很常見,並且只有一個站點,則不要使用嵌套結構,而要將所有鍵移到頂層對象等。 –

+0

沒有'simplejson'在這裏不會有幫助,因爲它只是將JSON解析爲相應的Python結構。 –

+0

反過來說,如果_can_可以超過一個站,你就不能擺脫'[0]'步驟,因爲如果有3個站,你需要能夠訪問#0,#1和# 2。你可以把這個列表變成一個由每個電臺的'STID'值(例如,'precipitation'''STATION'] ['KFNL'] ['OBSERVATIONS'['ob_start_time_1''''') ,但你無法擺脫它。 – abarnert

回答

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個字節。其實可以節省你的記憶,因爲如果你沒有存儲整個字典,只是子字典,Python可以垃圾回收結構的其餘部分。更重要的是,這種微型優化首先不值得擔心,直到(1)你的代碼正在工作,(2)你知道它是一個瓶頸。


我應該使用simpleJSON模塊來幫助這裏?

你爲什麼會這麼想? As its readme says

simplejson是Python 2.6和Python 3.0附帶的json庫的外部維護開發版本,但是維護與Python 2.5的向後兼容性。

換句話說,它要麼是您在stdlib中已經獲得的代碼,要麼是該代碼的舊版本。

有時不同庫,像ijson,可以幫助 - 例如,如果JSON結構是如此之大,你不能解析整個事情到內存中,或過於複雜,它更容易來描述你想要上攻什麼以SAX風格下降。但這在這裏沒有關係。

+0

謝謝你的全面迴應。我寫的第一個代碼涉及JSON /製作API調用。我很欣賞這個教訓! – 3722839

+1

@ jclark754:有一個我的老同事曾經使用的Firefox擴展。它將JSON文檔顯示爲樹狀結構,讓您可以在任意位置點擊,引導您完成從頂部到頂部的路徑,然後爲您提供(索引的JavaScript(而非Python ...但類似)代碼和/或迭代步驟到達那裏。不幸的是,我不記得它被稱爲什麼,但你可能想要尋找那樣的東西。他發現加速他的發展是有幫助的,甚至作爲一個JS專家(雖然我沒有),作爲一個新手,它可能更有助於可視化發生的事情。 – abarnert