以编程方式访问字典中任意深度嵌套的值

Jul*_*les 1 python search dictionary

我正在处理一个Python脚本,在其中给出了以下格式的字符串列表:['key1', 'key2', 'key2.key21.key211', 'key2.key22', 'key3']

列表中的每个值都对应于字典中的一个条目,对于结构类似的条目'key2.key21.key211',它们对应于(在此示例中)'key211'嵌套在其中的键'key21',自身嵌套在中'key2'

上面的列表对应于字典:

x = {
     'key1' : 'value1',
     'key2' : {
               'key21' : {
                          'key211': 'value211'
                         },
               'key22' : 'value22'
              },
     'key3' : 'value3'
    }
Run Code Online (Sandbox Code Playgroud)

名称不一定像常规一样key(n)+; food.vegetables.potato例如,它们可以是形式。我唯一可以保证的是,字典中的键名本身不包含.字符,并且字典中肯定包含原始列表中引用的所有条目。

我的问题是,给定这样的字符串列表,如何以编程方式访问字典中的相应条目?我可以想到一种使用的解决方案eval(),以及一种仅使用遍历/搜索的解决方案,但是我想避免调用eval(),并且给人的印象是,使用比较进行遍历会很慢(因为dicts不是搜索树),并且会带来很多讨厌的异常处理。

Eri*_*elt 5

一种方法是编写一个函数来访问嵌套字典中的键。

def deep_access(x,keylist):
     val = x
     for key in keylist:
         val = val[key]
     return val

s = 'key2.key21.key211'

print deep_access(x,s.split('.'))
Run Code Online (Sandbox Code Playgroud)

结果:

value211
Run Code Online (Sandbox Code Playgroud)

另一种方法,如果要使用与普通字典访问类似的语法,则可以提供子类dict并重写,__getitem__以在提供键元组时允许嵌套访问:

class NestedDict(dict):

    def __getitem__(self,keytuple):
        # if key is not a tuple then access as normal
        if not isinstance(keytuple, tuple):
            return super(NestedDict,self).__getitem__(keytuple)
        d = self
        for key in keytuple:
            d = d[key]
        return d

>>> nd = NestedDict(x)
>>> nd['key2']
{'key22': 'value22', 'key21': {'key211': 'value211'}}
>>> nd['key2','key22']
'value22'
>>> nd['key2','key21']
{'key211': 'value211'}
>>> nd['key2','key21','key211']
'value211'
Run Code Online (Sandbox Code Playgroud)

然后,您同样可以实现__setitem____delitem__需要。