2016-08-08 7 views
-2

У меня есть json-файл, который при загрузке в python с использованием json.loads() становится dictionary. Данные json - это nested dictionary, который может содержать ключ 'groups' внутри другого ключа 'groups'. Значения внутри ключа 'groups' представляют собой ключ 'name' и ключ 'properties'.Обновить значение словаря с помощью python

Ключ 'properties' имеет уникальный 'name' и ключ 'value'.

Моя цель состоит в том, чтобы искать 'groups' ключа, имеющего свою 'name' ключевое значение в качестве "SportCar", который имеет properties ключ, имеющий name ключевое значение в качестве "BMW", и только тогда, когда эти условия выполняются, обновить 'data' ключ от 'data':value1 к 'data':value2 ,

Пример JSON заключается в следующем

{ 
    "groups": [ 
    { 
     "name": "SportCar", 
     "properties": [ 
     { 
      "name": "BMW", 
      "value": { 
      "type": "String", 
      "encoding": "utf-8", 
      "data": "value1" 
      } 
     }, 
     { 
      "name": "Audi", 
      "value": { 
      "type": "Boolean", 
      "data": true 
      } 
     } 
     ], 
     "groups": [ 
     { 
      "name": "Trucks", 
      "properties": [ 
      { 
       "name": "Volvo", 
       "value": { 
       "type": "String", 
       "encoding": "utf-8", 
       "data": "value1" 
       } 
      } 
      ] 
     } 
     ] 
    }, 
    { 
     "name": "MotorCycle", 
     "properties": [ 
     { 
      "name": "Yamaha", 
      "value": { 
      "type": "String", 
      "encoding": "utf-8", 
      "data": "value1" 
      } 
     } 
     ], 
     "groups": [ 
     { 
      "name": "Speeders", 
      "properties": [ 
      { 
       "name": "prop2", 
       "value": { 
       "type": "String", 
       "encoding": "utf-8", 
       "data": "value1" 
       } 
      } 
      ] 
     } 
     ] 
    } 
    ] 
} 

выше JSON содержится в myjson22.json. Вот то, что я пытался до сих пор:

import json 
from pprint import pprint 

json_data=open('myjson22.json', 'r') 
data = json.load(json_data) 
#print(data) 

def get_recursively(search_dict, field): 
    """ 
    To read the json data as type dict and search all 'groups' keys for the 'name' key value value provided. 
    """ 
    fields_found = [] 

    for key, value in search_dict.items(): 

     if key == field: 
      fields_found.append(value) 

     elif isinstance(value, dict): 
      results = get_recursively(value, field) 
      for result in results: 
       fields_found.append(result) 

     elif isinstance(value, list): 
      for item in value: 
       if isinstance(item, dict): 
        more_results = get_recursively(item, field) 
        for another_result in more_results: 
         fields_found.append(another_result) 

    return fields_found 
get_recursively(data, ["properties"][0]) 

и выход был:

[[{'name': 'BMW', 
    'value': {'data': 'value1', 'encoding': 'utf-8', 'type': 'String'}}, 
    {'name': 'Audi', 'value': {'data': True, 'type': 'Boolean'}}], 
[{'name': 'Volvo', 
    'value': {'data': 'value1', 'encoding': 'utf-8', 'type': 'String'}}], 
[{'name': 'Yamaha', 
    'value': {'data': 'value1', 'encoding': 'utf-8', 'type': 'String'}}], 
[{'name': 'prop2', 
    'value': {'data': 'value1', 'encoding': 'utf-8', 'type': 'String'}}]] 
+5

Что вы пробовали до сих пор и почему он не в состоянии для достижения желаемых результатов? –

+1

'ONE property ', но свойства - это массив? – njzk2

+0

Пожалуйста, поделитесь с нами кодом и ошибкой. –

ответ

2

Способ реализации этого рекурсивного решения является с откатами. Когда в корневом ключе находятся не более 'groups' ключей, значение ключа 'name' сопоставляется с параметром groups_name, что является «SportCar» в нашем случае. Если это условие выполнено, проверьте значения внутри тех же ключей 'groups' (например, «SportCar») 'properties' и введите его значение 'name' с параметром properties_name (что в нашем случае является «BMW»). Если это второе условие также верно, то обновите значение ключа 'data' внутри одного и того же ключа 'properties' в соответствии с требованиями или верните (для обратного отслеживания).

import json 

json_data = open('myjson22.json', 'r') 

data = json.load(json_data) 

def get_recursively(myJson, groups_name, properties_name, value2): 

    if 'groups' in myJson.keys(): 
     # As there are multiple values inside 'groups' key 
     for jsonInsideGroupsKey in myJson['groups']: 
      get_recursively(jsonInsideGroupsKey, groups_name, properties_name, value2) 

    if 'name' in myJson.keys(): 
     # check for groups name 
     if myJson['name'] == groups_name: 
      # check for properties name 
      if myJson['properties'][0]['name'] == properties_name: 
       # Update value. The changes will persist as we backtrack because 
       # we are making the update at the original memory location 
       # and not on a copy. For more info see deep and shallow copy. 
       myJson['properties'][0]['value']['data'] = value2 
    return 

get_recursively(data,'SportCar','BMW','changedValue1') 
get_recursively(data,'Speeders','prop2','changedValue2') 
print data 

мой выход:

{u'groups ': [{u'name': u'SportCar», u'groups ': [{u'name': u'Trucks', и 'properties': [{u'name ': u'Volvo', u'value ': {u'data': u'value1 ', u'type': u'String ', u'encoding': u'utf -8 '}}]}], u'properties': [{u'name ': u'BMW', u'value ': {u'data': 'changedValue1', u'type ': u'String', u 'encoding': u'utf-8 '}}, {u'name': u'Audi ', u'value': {u'data ': True, u'type': u'Boolean '}}]} , {u'name ': u'MotorCycle', u'groups ': [{u'name': u'Speeders ', u'properties': [{u'name ': u'prop2', u'value ' : {u'data ': 'changedValue2', u'type': u'String ', u'encoding': u'utf-8 '}}]}], u'properties': [{u'name ': u' Yamaha ', u'value': {u'data ': u'value1', u'type ' : U'String», u'encoding ': u'utf-8'}}]}]}

prettified это будет выглядеть так:

{ 
    "groups": [ 
    { 
     "name": "SportCar", 
     "properties": [ 
    { 
     "name": "BMW", 
     "value": { 
     "type": "String", 
     "encoding": "utf-8", 
     "data": "ChangedValue1" 
     } 
    }, 
    { 
     "name": "Audi", 
     "value": { 
     "type": "Boolean", 
     "data": true 
     } 
    } 
     ], 
     "groups": [ 
    { 
     "name": "Trucks", 
     "properties": [ 
     { 
      "name": "Volvo", 
      "value": { 
      "type": "String", 
      "encoding": "utf-8", 
      "data": "value1" 
      } 
     } 
     ] 
    } 
     ] 
    }, 
    { 
     "name": "MotorCycle", 
     "properties": [ 
    { 
     "name": "Yamaha", 
     "value": { 
     "type": "String", 
     "encoding": "utf-8", 
     "data": "value1" 
     } 
    } 
     ], 
     "groups": [ 
    { 
     "name": "Speeders", 
     "properties": [ 
     { 
      "name": "prop2", 
      "value": { 
      "type": "String", 
      "encoding": "utf-8", 
      "data": "ChangedValue2" 
      } 
     } 
     ] 
    } 
     ] 
    } 
    ] 
} 
Смежные вопросы