繁体   English   中英

获取json中所有嵌套键的列表

[英]get list of all nested keys in a json

我有一个巨大的json,格式如下:

{
    "Name1": {
        "NNum": "11",
        "Node1": {
            "SubNodeA": "Thomas",
            "SubNodeB": "27"
        },
        "Node2": {
            "SubNodeA": "ZZZ",
            "SubNodeD": "XXX",
            "SubNodeE": "yy"
        },
        "Node3": {
                "child1": 11,
                "child2": {
                    "grandchild": {
                        "greatgrandchild1": "Rita",
                        "greatgrandchild2": "US"
                                }
                            }   
                }
            }
}

格式或键未定义,可以深入到我想要的键列表中,例如

keyList= ["Name1.NNum","Name1.Node1.SubNodeA",""Name1.Node1.SubNodeB","Name1.Node2.SubNodeA","Name1.Node2.SubNodeD","Name1.Node2.SubNodeE","Name1.Node3.child1","Name1.Node3.child2.grandchild.greatgrandchild1","Name1.Node3.child2.grandchild.greatgrandchild2"]

代码快照

def extract_values(obj):
    """Pull all values of specified key from nested JSON."""
    arr = []
    key_list = []
    parent = ""
    def extract(obj, arr,parent):
        """Recursively search for values of key in JSON tree."""
        if isinstance(obj, dict):
            grandparent = ""
            for k, v in obj.items():
                print ("k ............",k)
                parent = grandparent
                temp_parent = k
                print ("parent >>>>> ",parent)

                if isinstance(v, (dict, list)):
                    parent = temp_parent
                    print ("IF VALUE DICT .. parent ", parent)
                    extract(v, arr,parent)
                else:
                    grandparent = parent
                    parent = parent + "_" + temp_parent
                    print ("!!!!   NOT DICT :).... **** parent  ... ", parent)
                    arr.append(parent)

        elif isinstance(obj, list):
            for item in obj:
                extract(item, arr)
        #print ("arr >>>>>>>>>> ", arr)
        time.sleep(5)
        return arr

    results = extract(obj, arr,parent)
    return results

但这没有给出预期的输出。 预期产量:

keyList= ["Name1.NNum","Name1.Node1.SubNodeA",""Name1.Node1.SubNodeB","Name1.Node2.SubNodeA","Name1.Node2.SubNodeD","Name1.Node2.SubNodeE","Name1.Node3.child1","Name1.Node3.child2.grandchild.greatgrandchild1","Name1.Node3.child2.grandchild.greatgrandchild2"]

谁能帮我这个忙。 提前致谢

def getKeys(object, prev_key = None, keys = []):
    if type(object) != type({}):
        keys.append(prev_key)
        return keys
    new_keys = []
    for k, v in object.items():
        if prev_key != None:
            new_key = "{}.{}".format(prev_key, k)
        else:
            new_key = k
        new_keys.extend(getKeys(v, new_key, []))
    return new_keys

该解决方案假定可能具有子级的内部类型为字典。

那这个呢?

from collections import Mapping

def extract_paths(base_path, dd): 
    new_paths = [] 
    for key, value in dd.items(): 
        new_path = base_path + ('.' if base_path else '') + key 
        if isinstance(value, Mapping): 
            new_paths.extend(extract_paths(new_path, value)) 
        else: 
            new_paths.append(new_path) 
    return new_paths

extract_paths('', your_dict)

您可以执行简单的递归:

d = {
    "Name1": {
        "NNum": "11",
        "Node1": {
            "SubNodeA": "Thomas",
            "SubNodeB": "27"
        },
        "Node2": {
            "SubNodeA": "ZZZ",
            "SubNodeD": "XXX",
            "SubNodeE": "yy"
        },
        "Node3": {
                "child1": 11,
                "child2": {
                    "grandchild": {
                        "greatgrandchild1": "Rita",
                        "greatgrandchild2": "US"
                                }
                            }
                }
            }
}

def get_keys(d, curr_key=[]):
    for k, v in d.items():
        if isinstance(v, dict):
            yield from get_keys(v, curr_key + [k])
        elif isinstance(v, list):
            for i in v:
                yield from get_keys(i, curr_key + [k])
        else:
            yield '.'.join(curr_key + [k])

print([*get_keys(d)])

印刷品:

['Name1.NNum', 'Name1.Node1.SubNodeA', 'Name1.Node1.SubNodeB', 'Name1.Node2.SubNodeA', 'Name1.Node2.SubNodeD', 'Name1.Node2.SubNodeE', 'Name1.Node3.child1', 'Name1.Node3.child2.grandchild.greatgrandchild1', 'Name1.Node3.child2.grandchild.greatgrandchild2']

使用isinstance来检查dict or not被函数递归调用。 如果dict以递归方式附加到path打印path

def print_nested_keys(dic,path=''):
    for k,v in dic.items():
        if isinstance(v,dict):
            path+=k+"."
            yield from print_nested_keys(v,path)
        else:
            path+=k
            yield path

输出:

>>> [*print_nested_keys(d)] # Here, d is your nested dictionary
['Name1.NNum',
 'Name1.NNumNode1.SubNodeA',
 'Name1.NNumNode1.SubNodeASubNodeB',
 'Name1.NNumNode1.Node2.SubNodeA',
 'Name1.NNumNode1.Node2.SubNodeASubNodeD',
 'Name1.NNumNode1.Node2.SubNodeASubNodeDSubNodeE',
 'Name1.NNumNode1.Node2.Node3.child1',
 'Name1.NNumNode1.Node2.Node3.child1child2.grandchild.greatgrandchild1',
 'Name1.NNumNode1.Node2.Node3.child1child2.grandchild.greatgrandchild1greatgrandchild2']

您可以使用递归:

d = {'Name1': {'NNum': '11', 'Node1': {'SubNodeA': 'Thomas', 'SubNodeB': '27'}, 'Node2': {'SubNodeA': 'ZZZ', 'SubNodeD': 'XXX', 'SubNodeE': 'yy'}, 'Node3': {'child1': 11, 'child2': {'grandchild': {'greatgrandchild1': 'Rita', 'greatgrandchild2': 'US'}}}}}
def keys(d, c = []):
  return [i for a, b in d.items() for i in ([c+[a]] if not isinstance(b, dict) else keys(b, c+[a]))]

result = list(map('.'.join, keys(d)))

输出:

['Name1.NNum', 'Name1.Node1.SubNodeA', 'Name1.Node1.SubNodeB', 'Name1.Node2.SubNodeA', 'Name1.Node2.SubNodeD', 'Name1.Node2.SubNodeE', 'Name1.Node3.child1', 'Name1.Node3.child2.grandchild.greatgrandchild1', 'Name1.Node3.child2.grandchild.greatgrandchild2']

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM