2016-09-30 2 views
1

У меня есть следующий JSON-файл из API Я звоню:.Python верхнего уровня JSON Index

{ 
    "14500": [ 
    { 
     "5": { 
     "versionName": "VersionOne", 
     "expand": "executionSummaries", 
     "name": "Regression", 
     "projectId": 15006, 
     "startDate": "", 
     "executionSummaries": { 
      "executionSummary": [] 
     } 
     }, 
     "7": { 
     "versionName": "VersionOne", 
     "expand": "executionSummaries", 
     "versionId": 14500, 
     "projectId": 15006, 
     "startDate": "19/Sep/16", 
     "executionSummaries": { 
      "executionSummary": [] 
     } 
     }, 
     "-1": { 
     "versionName": "VersionOne", 
     "expand": "executionSummaries", 
     "name": "Ad hoc", 
     "modifiedBy": "", 
     "projectId": 15006, 
     "startDate": "", 
     "executionSummaries": { 
      "executionSummary": [] 
     } 
     }, 
     "recordsCount": 3 
    } 
    ], 
    "14501": [ 
    { 
     "-1": { 
     "versionName": "Version 2", 
     "expand": "executionSummaries", 
     "projectId": 15006, 
     "startDate": "", 
     "executionSummaries": { 
      "executionSummary": [] 
     } 
     }, 
     "recordsCount": 1 
    } 
    ], 
} 

мне нужно перебирать верхний уровень, и следующий уровень (напр «14500» и " 5 "," 7 "и т. Д.), Чтобы найти ключи и значения. Так, например, мне нужно выполнить поиск по всему файлу JSON, чтобы найти имя, соответствующее «Регрессии», и найти этот набор значений данных для «ProjectID» и, возможно, других строк. Я ранее делал это, используя данные ["level1"] [0] ["level2"] и т. Д., Но в этом случае числа никогда не будут одинаковыми, поэтому я не знаю, как их называть. Я написал следующее после просмотра некоторых сообщений здесь, но он работает только на одном уровне, а не на следующем уровне в JSON.

request = requests.get(getCyclesURL, headers=headers) 
requestData = json.loads(request.text) 
requestDataKeys = requestData.keys 

for k in requestDataKeys(): 
    dictionaryIDs = requestData[k] 
    for m in requestDataKeys: 
     newDictionaryIDs = requestData[k][m] 
     for dict in newDictionaryIDs: 
      if dict['versionName'] == versionName: 
       versionID = dict['versionID'] 
       print '%s: %s'%(versionName, versionID) 
+0

@MMF это делает, поскольку они не вызывали метод при назначении. – jonrsharpe

ответ

0

Вот частичный сценарий, специально разработанный для вашего точного ввода. Если он найдет name: regression на соответствующем уровне, он печатает несколько связанных значений.

for k, list_of_dicts in requestData.items(): 
    for d in list_of_dicts: 
     for k, v in d.items(): 
      if isinstance(v, dict) and v.get('name') == "Regression": 
       print '%s: %s %s'%(v.get('projectId'), 
            v.get('versionName'), 
            v.get('versionId')) 
+0

Отлично, большое спасибо! – JustMe

0
def find_in_dicts(d, key, value): #This finds all dictionaries that has the given key and value 
    for k, v in d.items(): 
     if k == key: 
      if v == value: 
       yield d 
     else: 
      if isinstance(v, dict): 
       for i in find_in_dicts(v, key, value): 
        yield i 
      elif isinstance(v, list) and isinstance(v[0], dict): 
       for item in v: 
        for i in find_in_dicts(item, key, value): 
         yield i 

Это должно работать recursivly независимо от того, насколько глубоко ваша структура данных становится. Я не могу проверить это на данный момент, но я надеюсь, что это на elast дает вам некоторую идею.

1

Отъезд удивительная boltons библиотека! Он имеет функцию remap, которая может быть излишним в вашем случае, но это хорошо, о чем нужно знать. Вот элегантный способ извлечь все dicts с 'name': 'Regression' из вашей вложенной структуры данных:

from boltons.iterutils import remap 

# Copy your actual data here 
data = {'14500': [{'5': {'name': 'Regression'}, '7': {'name': 'Ad hoc'}}]} 

regressions = [] 

def visit(path, key, value): 
    if isinstance(value, dict) and value.get('name') == 'Regression': 
     # You can do whatever you want here! 
     # If you're here then `value` is a dict 
     # and its `name` field equals to 'Regression'. 
     regressions.append(value) 
    return key, value 

remap(data, visit=visit, reraise_visit=False) 

assert regressions == [{'name': 'Regression'}] 

Если вам нужно только dicts на определенном уровне, вы можете также проверить длину path в функции visit.

Смежные вопросы