2016-08-08 25 views
-2

Ich habe eine JSON-Datei, die beim Laden in Python mit json.loads() wird zu einem dictionary. Die JSON-Daten sind eine nested dictionary, die einen 'groups' Schlüssel innerhalb eines anderen 'groups' Schlüssels enthalten kann. Die Werte innerhalb des Schlüssels 'groups' sind ein Schlüssel 'name' und ein Schlüssel 'properties'.Aktualisieren Sie einen Wörterbuch Wert mit Python

Jeder Schlüssel 'properties' hat einen eindeutigen Schlüssel 'name' und 'value'.

Mein Ziel ist es für einen 'groups' Schlüssel, dessen 'name' Schlüsselwert als "SportCar", welches einen properties Schlüssel mit einem name Schlüsselwert als "BMW", und nur zu suchen, wenn diese Bedingungen erfüllt sind, aktualisieren Sie die 'data' Schlüssel 'data':value1-'data':value2 .

Ein Beispiel des json ist als

{ 
    "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" 
       } 
      } 
      ] 
     } 
     ] 
    } 
    ] 
} 

Die obige json in myjson22.json enthalten ist, folgt. Hier ist, was ich versucht habe, so weit:

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]) 

und der Ausgang war:

[[{'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

Was haben Sie bisher versucht und warum es scheitern um die gewünschten Ergebnisse zu erzielen? –

+1

'Eine Eigenschaft', aber Eigenschaften ist ein Array? – njzk2

+0

Bitte teilen Sie den Code und den Fehler, falls vorhanden. –

Antwort

2

Ein Weg, um diese rekursive Lösung zu implementieren mit Backtracking ist. Wenn keine weiteren 'groups' Schlüssel innerhalb des Stammschlüssels gefunden werden, wird der 'name' Schlüsselwert mit groups_name Parameter verglichen, der in unserem Fall 'SportCar' ist. Wenn diese Bedingung erfüllt ist, überprüfen Sie die Werte innerhalb desselben Schlüssels 'groups' (d. H. Schlüssel "SportCar") 'properties' und passen Sie seinen 'name' Schlüsselwert mit dem properties_name Parameter (in unserem Fall "BMW"). Wenn diese zweite Bedingung ebenfalls zutrifft, aktualisieren Sie den Schlüsselwert 'data' innerhalb des gleichen Schlüssels 'properties', je nach den Anforderungen, oder geben Sie andernfalls (für Backtracking) zurück.

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 

meine Ausgabe:

{u'groups ': [{u'name': u'SportCar‘, u'groups ': [{u'name': u'Trucks', u 'Eigenschaften': [{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 ': Wahr, u'type': u'Boolean '}}]} , {u'name ': u'MotorCycle', u'groups ': [{u'name': u'Speeders ',' 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'}}]}]}

verniedlicht es wie aussehen:

{ 
    "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" 
      } 
     } 
     ] 
    } 
     ] 
    } 
    ] 
}