我有一个json文件,使用json.loads()
在python中加载时会成为dictionary
。 json数据是nested dictionary
,可以在另一个'groups'
密钥中包含'groups'
密钥。 'groups'
密钥中的值是'name'
密钥和'properties'
密钥。
每个'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'}}]]
答案 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'群组':[{u'姓名':你' SportCar',你'群组':[{你'名称&# 39;:你'卡车',你的财产':[{u'名称':你'沃尔沃',你'价值': {u'数据':你' value1',你'键入':你'字符串',你'编码':你' utf-8'}}]}],u'属性':[{u'名称':你'宝马',你'价值': {u'数据':'changedValue1'
,u'键入':u'字符串',u'编码':u' utf-8& #39;}},{u'姓名':你'奥迪',你'价值':{u'数据':是的,你'键入':u'布尔'}}}},{u'名称':你' MotorCycle',你' groups':[{u&# 39;姓名':你' Speeders',u'属性':[{u' name&#39 ;: u' prop2',u' value& #39;:{u'数据':'changedValue2'
,你'键入':你'字符串',u'编码':你' ; utf-8'}}]}],u'属性':[{u' name&#39 ;: u' Yamaha',u' value' :{u'数据':你' val ue1',你'键入':你'字符串',u'编码':u' utf-8'}}]}]}
美化它看起来像:
{
"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"
}
}
]
}
]
}
]
}