2016-08-08 13 views
-2

私はjsonファイルを持っています。これは、json.loads()を使用してPythonでロードすると、dictionaryになります。 jsonデータはnested dictionaryであり、別の'groups'キーの中に'groups'キーを含めることができます。 'groups'キー内の値は、'name'キーと'properties'キーです。Pythonを使用して辞書の値を更新する

'properties'キーには、一意の'name'キーと'value'キーがあります。

私の目的は "BMW"として nameキー値を持つ properties鍵を持っている "SportCar"としての 'name'キー値を持つ 'groups'キーを検索し、これらの条件が満たされた場合にのみ、 'data':value1 'data':value2から 'data'キーを更新することです

。上記JSONはmyjson22.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の例です。

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

を:u'utf-8'}}]}]}

は、それはのようになります清書あなたが望む結果を達成するために? –

+1

「ONEプロパティ」ですが、プロパティは配列ですか? – njzk2

+0

コードとエラーがあれば教えてください。 –

答えて

2

この再帰的なソリューションを実装する方法は、バックトラックです。 'groups'キーがルートキーの内部にネストされていない場合、'name'キー値はgroups_nameパラメータ(この場合は 'SportCar')と一致します。この条件が満たされている場合、同じ'groups'キー(つまり 'SportCar'キー)キー内の値を確認し、その'name'キー値とproperties_nameパラメータ(ここでは 'BMW')を一致させます。この2番目の条件も当てはまる場合は、必要に応じて'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'、U 'プロパティ':[{u'name ':u'Volvo'、u'value ':{u'data':u'value1 '、u'type':u'String '、u'encoding':u'utf U'properties ':[u'name':u'BMW '、u'value':{u'data ':'changedValue1'、u'type':u'String '、u' 'エンコーディング':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 'ヤマハ、u'value ':{u'data':u'value1 '、u'type' :u'String」、u'encoding ':

あなたがこれまでに試してみましたが、なぜそれが失敗したのは何
{ 
    "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" 
      } 
     } 
     ] 
    } 
     ] 
    } 
    ] 
} 
関連する問題