Python:动态访问嵌套字典键?

时间:2016-10-02 15:41:09

标签: python python-2.7 dictionary

首先,您不知道要访问哪个密钥,是否有一些简单的方法来访问嵌套字典密钥?

例如:

dct = {'label': 'A', 'config': {'value': 'val1'}}

在这本词典中,我需要访问可通过label密钥访问的另一个词典中的value键或config键。

这取决于州。

例如,如果我们有一个名为label的变量,那么如果:

label = True
if label:
   key = 'label'

在这种情况下它很容易:

dct[key]

现在如果label为false并且我需要访问嵌套字典,我怎么能动态指定它,所以我不需要在每个迭代项上使用ifs(我的意思是每次使用label而不是{ {1}},因为在完成value字典的字典上的迭代之前我会知道吗?

像:

dct

3 个答案:

答案 0 :(得分:2)

如果您知道要遍历的密钥,可以尝试以下操作。这适用于任何级别的嵌套dicts。

dct = {'label': 'A', 'config': {'value': 'val1'}}

label = True
key = ('label',)
if not label:
    key = ('config', 'value')

ret = dct
for k in key:
  ret = ret[k]

print ret

答案 1 :(得分:0)

扩展@Barun的工作,并可能帮助回答@Bhavani在嵌套字典中重新设置的问题,这是一种动态访问或设置嵌套字典键的通用解决方案。 Python 3.7。

from typing import List

class DynamicAccessNestedDict:
    """Dynamically get/set nested dictionary keys of 'data' dict"""

    def __init__(self, data: dict):
        self.data = data

    def getval(self, keys: List):
        data = self.data
        for k in keys:
            data = data[k]
        return data

    def setval(self, keys: List, val) -> None:
        data = self.data
        lastkey = keys[-1]
        for k in keys[:-1]:  # when assigning drill down to *second* last key
            data = data[k]
        data[lastkey] = val

您只需将字典包装在此类的实例中,然后通过传递键列表进行获取和设置。

dct = {'label': 'A', 'config': {'value': 'val1'}}

d = DynamicAccessNestedDict(dct)
assert d.getval(["label"]) == "A"
assert d.getval(["config", "value"]) == "val1"

# Set some new values
d.setval(["label"], "B")
d.setval(["config", "value"], "val2")

assert d.getval(["label"]) == "B"
assert d.getval(["config", "value"]) == "val2"

答案 2 :(得分:0)

from functools import reduce
import operator
#db is dictionary which need to update
#keys is a list need to depth of keys in a order
#value targeted value to update in dictionary 
class Dict_update:
    def set_by_path(self, db, keys, value):
        """Set a value in a nested object in db by keys sequence."""
        for index in range(1,len(keys)):
            subitem = self.get_by_path(db, keys[:index])
            if not isinstance(subitem, dict):
                self.get_by_path(db, keys[:index][:-1])[keys[:index][-1]] = {}
        self.get_by_path(db, keys[:-1])[keys[-1]] = value
        return db

    def get_by_path(self, db, keys):

        try: return reduce(operator.getitem, keys, db)
        except Exception as e:
            return None