在嵌套字典python中搜索值

Lax*_*khi 10 python python-2.7 python-3.x

搜索值并获取父词典名称(键):

Dictionary = {dict1:{
        'part1': {
            '.wbxml': 'application/vnd.wap.wbxml',
            '.rl': 'application/resource-lists+xml',    
        },
        'part2':
            {'.wsdl': 'application/wsdl+xml',
            '.rs': 'application/rls-services+xml',
            '.xop': 'application/xop+xml',
            '.svg': 'image/svg+xml',
            },
        'part3':{...}, ...

   dict2:{
          'part1': {    '.dotx': 'application/vnd.openxmlformats-..'                           
            '.zaz': 'application/vnd.zzazz.deck+xml',
            '.xer': 'application/patch-ops-error+xml',}  
          },
          'part2':{...},
          'part3':{...},...  

    },...
Run Code Online (Sandbox Code Playgroud)

在上面的字典中,我需要搜索如下值:"image/svg+xml".其中,没有值在字典中重复.如何搜索"image/svg+xml"?所以它应该返回字典中的父键{ dict1:"part2" }.

请注意:解决方案应该工作未修改两个的Python 2.7和Python 3.3.

jfs*_*jfs 16

这是一个简单的递归版本:

def getpath(nested_dict, value, prepath=()):
    for k, v in nested_dict.items():
        path = prepath + (k,)
        if v == value: # found value
            return path
        elif hasattr(v, 'items'): # v is a dict
            p = getpath(v, value, path) # recursive call
            if p is not None:
                return p
Run Code Online (Sandbox Code Playgroud)

例:

print(getpath(dictionary, 'image/svg+xml'))
# -> ('dict1', 'part2', '.svg')
Run Code Online (Sandbox Code Playgroud)


Kob*_*ohn 8

这是嵌套dicts的迭代遍历,另外跟踪导致特定点的所有键.因此,只要在dicts中找到正确的值,您就已经拥有了获得该值所需的密钥.

如果将它放在.py文件中,下面的代码将按原样运行.该find_mime_type(...)函数返回将从原始字典中获取所需值的键序列.该demo()功能显示了如何使用它.

d = {'dict1':
         {'part1':
              {'.wbxml': 'application/vnd.wap.wbxml',
               '.rl': 'application/resource-lists+xml'},
          'part2':
              {'.wsdl': 'application/wsdl+xml',
               '.rs': 'application/rls-services+xml',
               '.xop': 'application/xop+xml',
               '.svg': 'image/svg+xml'}},
     'dict2':
         {'part1':
              {'.dotx': 'application/vnd.openxmlformats-..',
               '.zaz': 'application/vnd.zzazz.deck+xml',
               '.xer': 'application/patch-ops-error+xml'}}}


def demo():
    mime_type = 'image/svg+xml'
    try:
        key_chain = find_mime_type(d, mime_type)
    except KeyError:
        print ('Could not find this mime type: {0}'.format(mime_type))
        exit()
    print ('Found {0} mime type here: {1}'.format(mime_type, key_chain))
    nested = d
    for key in key_chain:
        nested = nested[key]
    print ('Confirmation lookup: {0}'.format(nested))


def find_mime_type(d, mime_type):
    reverse_linked_q = list()
    reverse_linked_q.append((list(), d))
    while reverse_linked_q:
        this_key_chain, this_v = reverse_linked_q.pop()
        # finish search if found the mime type
        if this_v == mime_type:
            return this_key_chain
        # not found. keep searching
        # queue dicts for checking / ignore anything that's not a dict
        try:
            items = this_v.items()
        except AttributeError:
            continue  # this was not a nested dict. ignore it
        for k, v in items:
            reverse_linked_q.append((this_key_chain + [k], v))
    # if we haven't returned by this point, we've exhausted all the contents
    raise KeyError


if __name__ == '__main__':
    demo()
Run Code Online (Sandbox Code Playgroud)

输出:

在这里找到image/svg + xml mime类型:['dict1','part2','.svg']

确认查找:image/svg + xml