我有一个列表,其中包含JSON中的节点的路由.如何基于此路线访问节点



我有一个列表,其中包含以下格式的数据。

Data format: "1.3.4.2.1", "1.45.67.32.2", ...(the strings separated by dots 
can be of varying lengths)

此字符串表示字符串中的"状态"节点的路由和"最后一个索引"表示必须分配给状态节点中" @default"属性的值。

我有以下格式的JSON。

json_tree = 
{
  "Gardens": {
    "Seaside": {
      "@loc": "porch",
      "@myID": "1.2.3",
      "Tid": "1",
      "InfoList": {
        "status": {
          "@default": "0",
          "@myID": "26"
        },
        "count": {
          "@default": "0",
          "@myID": "1"
        }
      },
      "BackYard": {
        "@loc": "backyard",
        "@myID": "75",
        "Tid": "2",
        "InfoList": {
          "status": {
            "@default": "6",
            "@myID": "32"
          },
          "count": {
            "@default": "0",
            "@myID": "2"
          }
        }
      }
    }
  }
}

在这种情况下,我的路由列表包含以下信息。

route_list = ["1.2.3.26.4","1.2.3.75.32.2",...] # this json_tree could have many more layers in the format shown above
Note: '1.2.3.26" is the route to the "status" node in "Gardens" and "4" is the value to be assigned to the "@default" node in the "status".
Note: '1.2.3.75.32" is the route to the "status" node in "BackYard" and "2" is the value to be assigned to the "@default" node in the "status".

到目前为止,我有以下方法。我无法从这里走得更远。

for item in route_list:
   UpdateJsonTree(json_tree, item)
def UdpateJsonTree(json_tree, item):
   # I am unsure on how to parse the json tree based on the route given
   # and update the '@default' value of the status node 

任何帮助将不胜感激。谢谢。

此方法首先建立一个路由大师,该路由主人包含每个路由的列表条目,以检查(底部显示(。

一旦可用路由主机,路由检查就直接向前。

flatten来自这里的179点答案

如果您需要任何澄清,请告诉我。

这是代码:

import _collections_abc
import itertools
from pprint import pprint
l1 = [
    '1.2.3.26.4',
    '1.2.3.75.32.2'
]
json_tree = {
    "Gardens": {
        "Seaside": {
            "@loc": "porch",
            "@myID": "1.2.3",
            "Tid": "1",
            "InfoList": {
                "status": {
                    "@default": "0",
                    "@myID": "26"
                },
                "count": {
                    "@default": "0",
                    "@myID": "1"
                }
            },
            "BackYard": {
                "@loc": "backyard",
                "@myID": "75",
                "Tid": "2",
                "InfoList": {
                    "status": {
                        "@default": "6",
                        "@myID": "32"
                    },
                    "count": {
                        "@default": "0",
                        "@myID": "2"
                    }
                }
            }
        }
    }
}

def flatten(d, parent_key='', sep='_'):
    """Return flattened dict as list"""
    items = []
    for k, v in d.items():
        new_key = parent_key + sep + k if parent_key else k
        if isinstance(v, _collections_abc.MutableMapping):
            items.extend(flatten(v, new_key, sep=sep).items())
        else:
            items.append((new_key, v))
    return dict(items)

def add_id(path, id_value):
    """Update list of @myID paths"""
    id_list.append([path, id_value])

def update_json(path, value):
    """Update the json_data with the default value"""
    l_bracket_q = "['"
    r_bracket_q = "']"
    at_default = "['@default']"
    result = ''
    cmd = "json_tree"
    for key in path:
        cmd += l_bracket_q + key + r_bracket_q
    cmd += at_default
    cmd += ' = value'
    exec(cmd)

flat_list = flatten(json_tree)
id_list = []
#  Loop the flattened list filtering for ID's, excluding the ones in count
for k, v in [x for x in flat_list.items() if '@myID' in x[0] and 'count' not in x[0]]:
    add_id(k, v)
route_list = []
# start building the route list from the filtered id list
for id_entry in id_list:
    route_list.append(
        [[x for x in id_entry[0].split('_') if x != '@myID'],
         [y for y in id_entry[1].split('.')]])
route_master = []
#  generate the route master to include the path and the full route (as list not 1.2.3)
for id_entry in id_list:
    s1 = id_entry[0].split('_')
    tmp_route = []
    tmp_list = []
    for i in range(len(s1)):
        if s1[i] == '@myID':
            break
        tmp_list.append(s1[i])
        for rte in route_list:
            if tmp_list == rte[0]:
                tmp_route.append(rte[1])
    route_item = list(itertools.chain(*tmp_route))
    tmp_list.append(route_item)
    route_master.append(tmp_list)
#  break out the default value from the route of the main driver file
l2 = list(zip(['.'.join(x.split('.')[:-1]) for x in l1], [x.split('.')[-1] for x in l1]))
#  loop the routes to process and update when found
for route, default in l2:
    for check_it in route_master:
        if route.split('.') == check_it[-1]:
            update_json(check_it[:-1], default)
#  print results
pprint(json_tree)

结果:

{'Gardens': {'Seaside': {'@loc': 'porch',
                         '@myID': '1.2.3',
                         'BackYard': {'@loc': 'backyard',
                                      '@myID': '75',
                                      'InfoList': {'count': {'@default': '0',
                                                             '@myID': '2'},
                                                   'status': {'@default': '2',
                                                              '@myID': '32'}},
                                      'Tid': '2'},
                         'InfoList': {'count': {'@default': '0', '@myID': '1'},
                                      'status': {'@default': '4',
                                                 '@myID': '26'}},
                         'Tid': '1'}}}

路线主:

['Gardens', 'Seaside', ['1', '2', '3']]
['Gardens', 'Seaside', 'InfoList', 'status', ['1', '2', '3', '26']]
['Gardens', 'Seaside', 'BackYard', ['1', '2', '3', '75']]
['Gardens', 'Seaside', 'BackYard', 'InfoList', 'status', ['1', '2', '3', '75', '32']]

最新更新