在字典中以编程方式访问任意深度嵌套的值 [英] Programmatically accessing arbitrarily deeply-nested values in a dictionary

查看:101
本文介绍了在字典中以编程方式访问任意深度嵌套的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究一个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'
}

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



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

解决方案

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

  def deep_access(x,keylist):
val = x
键盘中的键:
val = val [key]
return val

s ='key2.key21.key211'

print deep_access(x,s.split('。'))

结果:

  value211 






另一种方法,如果你想使用与常规字典访问类似的语法,您可以将 dict 子类化,并覆盖 __ getitem __ 以允许嵌套访问提供了元组元素:

  class NestedDict(dict):

def __getitem __(self, keytuple):
#如果键不是元组然后正常访问
如果不是isinstance(keytuple,tuple):
返回超级(NestedDict,self).__ getitem __(keytuple)
d = self
keytuple中的key:
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'

然后,您可以根据需要类似地实现 __ setitem __ __ delitem __


I'm working on a Python script where I'm given lists of strings of the format: ['key1', 'key2', 'key2.key21.key211', 'key2.key22', 'key3'].

Each value in the list corresponds to an entry in a dictionary, and for entries structured like 'key2.key21.key211', they correspond to (in this example), a key 'key211' nested within 'key21', itself nested inside 'key2'.

The above list corresponds to the dictionary:

x = {
     'key1' : 'value1',
     'key2' : {
               'key21' : {
                          'key211': 'value211'
                         },
               'key22' : 'value22'
              },
     'key3' : 'value3'
    }

The names are not necessarily as regular as key(n)+; they can be of the form food.vegetables.potato, for example. The only guarantees I have is that the key names themselves, in the dictionary, do not contain the . character, and that the dictionary definitely contains all the entries referenced in the original list.

My question is, given such a list of strings, how do I programmatically access the corresponding entries in a dictionary? I can think of a solution using eval(), as well as one using just a traversal/search, but I want to avoid calls to eval(), and I get the impression that a traversal with comparisons would be slow (since dicts aren't search trees), and would entail a lot of nasty exception handling.

解决方案

One approach is to write a function to access keys in nested dicts.

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('.'))

result:

value211


Another approach, if you want to use similar syntax as a normal dictionary access you could subclass dict and override __getitem__ to allow for nested access when a tuple of keys is provided:

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'

You can then similarly implement __setitem__ and __delitem__ as needed.

这篇关于在字典中以编程方式访问任意深度嵌套的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆