繁体   English   中英

Python 递归 function 以匹配嵌套字典中的键值和返回路径

[英]Python recursive function to match key values and return path in nested dictionary

我有一个嵌套字典,我正在尝试编写一个 function 来查找匹配的键,并将路径中的所有键返回到匹配的键。 给定下面的示例嵌套字典:

nested_dict = {'a': {'b':{'c': 'd',
                      'e': 'f'},
                 'g': {'h': {'i': 'j'}}},
           'k': {'l': 'm',
                 'n': 'o',
                 'p': {'q': 'r',
                       's': 't'}}}

我希望 function getpath 返回:

getpath(s) = ['k','p','s']
getpath(i) = ['a', 'g','h','i']

我在下面编写了递归 function 来尝试完成此操作,但它没有返回任何内容,我希望我很接近但犯了一个小错误:

start_keys = list()
def getpath(nested_dict,search_value,keys):
    # extract keys from the dict
    dict_keys = list(nested_dict.keys())
    # loop through dict keys
    for key in dict_keys:
        # append key to keys
        keys.append(key)
        level_down = nested_dict[key]
        # check if the key matches the target value
        if search_value.lower()==key.lower():
            # if it does match, we're good, so return keys
            return(keys)
        else:
            # since it didn't match, we attempt to go further down
            if type(level_down) is dict:
                # run getpath on it
                getpath(level_down, search_value, keys)
            else:
                # if we can't go further down, it means we got to the end without finding a match, so we wipe out keys
                keys = list()

您可以通过仅检查当前键是否与search_value匹配来简化递归,如果不匹配,则关联值是否为dict ,在这种情况下,您将递归:

def getpath(nested_dict, search_value):
    # loop through dict keys
    for key in nested_dict.keys():
        # have we found the search value?
        if key == search_value:
            return [key]
        # if not, search deeper if this value is a dict
        if type(nested_dict[key]) is dict:
            path = getpath(nested_dict[key], search_value)
            if path is not None:
                return [key] + path
    # no match found in this part of the dict
    return None


getpath(nested_dict,'s')     # ['k','p','s']
getpath(nested_dict, 'i')    # ['a', 'g','h','i']

您可以将递归与生成器一起使用:

def getpath(k, d, c = []):
   for a, b in getattr(d, 'items', lambda :[])():
      if a == k:
         yield from (c+[a])
      else:
          yield from getpath(k, d = b, c = c+[a])
   

nested_dict = {'a': {'b': {'c': 'd', 'e': 'f'}, 'g': {'h': {'i': 'j'}}}, 'k': {'l': 'm', 'n': 'o', 'p': {'q': 'r', 's': 't'}}}
print(list(getpath('s', d=nested_dict)))
print(list(getpath('i', d=nested_dict)))

Output:

['k', 'p', 's']
['a', 'g', 'h', 'i']

暂无
暂无

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

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