在嵌套字典中搜索键

Jav*_*aSa 2 python

我在Python中有一个JSON对象,表示为嵌套的字典列表.(字典的某些值本身就是字典,依此类推.)

我希望能够在这个嵌套字典结构的所有分支上搜索一个键.
当我找到密钥时,我希望能够返回通向它的完整密钥路径.

例如:我正在寻找具有"特殊地址密钥"的"特殊代理",但并非所有特殊代理都拥有它,以及那些在其JSON中的不一致路径中拥有它的人.

所以我搜索关键Special Address code.结果应该返回:

/'People'/'SpecialAgents'/'007'/'Special Address code'/  
Run Code Online (Sandbox Code Playgroud)

所以我将能够以这种方式获得其信息:

json_obj['People']['SpecialAgents']['007']['Special Address code']
Run Code Online (Sandbox Code Playgroud)

请注意,这与此问题类似,但我需要找到所有密钥实例的完整路径.

Jos*_*ush 11

你需要一个递归搜索.

您可以定义一个函数来深入搜索输入json:

def find_in_obj(obj, condition, path=None):

    if path is None:
        path = []    

    # In case this is a list
    if isinstance(obj, list):
        for index, value in enumerate(obj):
            new_path = list(path)
            new_path.append(index)
            for result in find_in_obj(value, condition, path=new_path):
                yield result 

    # In case this is a dictionary
    if isinstance(obj, dict):
        for key, value in obj.items():
            new_path = list(path)
            new_path.append(key)
            for result in find_in_obj(value, condition, path=new_path):
                yield result 

            if condition == key:
                new_path = list(path)
                new_path.append(key)
                yield new_path 
Run Code Online (Sandbox Code Playgroud)

然后我们可以在这个类似的SO问题中使用示例JSON 来测试递归搜索:

In [15]: my_json = { "id" : "abcde",
   ....:   "key1" : "blah",
   ....:   "key2" : "blah blah",
   ....:   "nestedlist" : [ 
   ....:     { "id" : "qwerty",
   ....:       "nestednestedlist" : [ 
   ....:         { "id" : "xyz",
   ....:           "keyA" : "blah blah blah" },
   ....:         { "id" : "fghi",
   ....:           "keyZ" : "blah blah blah" }],
   ....:       "anothernestednestedlist" : [ 
   ....:         { "id" : "asdf",
   ....:           "keyQ" : "blah blah" },
   ....:         { "id" : "yuiop",
   ....:           "keyW" : "blah" }] } ] } 
Run Code Online (Sandbox Code Playgroud)

让我们找到键'id'的每个实例,并返回让我们在那里的完整路径:

In [16]: for item in find_in_obj(my_json, 'id'):
   ....:     print item
   ....:     
['nestedlist', 0, 'nestednestedlist', 0, 'id']
['nestedlist', 0, 'nestednestedlist', 1, 'id']
['nestedlist', 0, 'id']
['nestedlist', 0, 'anothernestednestedlist', 0, 'id']
['nestedlist', 0, 'anothernestednestedlist', 1, 'id']
['id']
Run Code Online (Sandbox Code Playgroud)