Python获得嵌套的dict元素

时间:2016-02-26 22:29:14

标签: python

是否有一种简单,简洁的方法可以从嵌套的dict中获取值,如果不存在则获取None?

d1 = None
d2 = {}
d3 = {"a": {}}
d4 = {"a": {"b": 12345}}
ds = [d1, d2, d3, d4]


def nested_get(d):
    # Is there a simpler concise one-line way to do exactly this, query a nested dict value, and return None if
    # it doesn't exist?
    a_val = d.get("a") if d else None
    b_val = a_val.get("b") if a_val else None
    return b_val

if __name__ == "__main__":
    bs = [nested_get(d) for d in ds]
    print("bs={}".format(bs))

4 个答案:

答案 0 :(得分:1)

这应该有效:

getTbyName

答案 1 :(得分:1)

好的,使用一个简单的自定义函数,我可以这样做,作为一个简洁的解决方案:

d1 = None
d2 = {}
d3 = {"a": {}}
d4 = {"a": {"b": 12345}}
ds = [d1, d2, d3, d4]


def get_nested_dict_value(d, *args):
    for a in args:
        d = d.get(a) if d else None
    return d


if __name__ == "__main__":
    bs = [get_nested_dict_value(d, "a", "b") for d in ds]
    print("bs={}".format(bs))

答案 2 :(得分:1)

如果你想变得有点脏,你可以创建一个自定义类来扩展典型字典处理下标的方式。

class QueryDict(dict):
    def __getitem__(self, keys):
        current = self
        try:
            for key in keys:
                current = dict.__getitem__(current, key)
            return current
        except (TypeError, KeyError):
            return None


d = {"a": {"b": {"c": 12345}}}
d = QueryDict(d)
print d['a','b','c'] # 12345
print d['a,c,e'] # None

或者,如果您尝试动态调用条目,最好允许通过逗号分隔的字符串传入密钥。

class QueryDict(dict):
    def __getitem__(self, key_string):
        current = self
        try:
            for key in key_string.split(','):
                current = dict.__getitem__(current, key)
            return current
        except (TypeError, KeyError):
            return None


d = {"a": {"b": {"c": 12345}}}
d = QueryDict(d)
print d['a,b,c'] # 12345.
print d['a,c,e'] # None

答案 3 :(得分:0)

如果您更愿意指定"路径"嵌入式dict作为字符串路径(如目录)而不是一组单独的键,这已经满足了我们的需求:

def deep_get(d, path, default=None):
    """Get a deeply nested value in a dict based on multiple keys

    :param d: The dictionary
    :param path: The key path to search separated by '/'
    :param default: The default value to return if there is nothing
    :returns: The value at the given path or the default
    """
    dd = d
    split = path.split("/")
    for i, key in enumerate(split):
        try:
            dd = dd.get(key, {})
        except AttributeError as exc:
            p = "/".join(split[0:i])
            raise AttributeError("{} at {}".format(exc.message, p)), \
                None, sys.exc_info()[2]
    return dd or default

用法就像

一样简单
d = {
  'a': {
    'b': {
      'c': {
        'd': "hi!"
      }
    }
  }
}

print deep_get(d, 'a/b/c/d')