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

时间:2019-07-08 07:53:04

标签: python json python-3.x

我有一个巨大的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"]

有人可以帮我吗? 预先感谢

5 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

那呢?

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)

答案 2 :(得分:1)

您可以进行简单的递归:

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

答案 3 :(得分:1)

使用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']

答案 4 :(得分:0)

您可以使用递归:

-lpthread

输出:

pthread_attr_getdetachstate