检查字典中是否存在嵌套键的优雅方法? [英] Elegant way to check if a nested key exists in a dict?

查看:53
本文介绍了检查字典中是否存在嵌套键的优雅方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有更易读的方法来检查一个隐藏在字典中的键是否存在而不独立检查每个级别?

Is there are more readable way to check if a key buried in a dict exists without checking each level independently?

假设我需要在埋藏的对象中获取此值(示例取自维基数据):

Lets say I need to get this value in a object buried (example taken from Wikidata):

x = s['mainsnak']['datavalue']['value']['numeric-id']

为了确保这不会以运行时错误结束,有必要像这样检查每个级别:

To make sure that this does not end with a runtime error it is necessary to either check every level like so:

if 'mainsnak' in s and 'datavalue' in s['mainsnak'] and 'value' in s['mainsnak']['datavalue'] and 'nurmeric-id' in s['mainsnak']['datavalue']['value']:
    x = s['mainsnak']['datavalue']['value']['numeric-id']

我能想到的另一种解决方法是将其包装到一个 try catch 结构中,我觉得这对于这样一个简单的任务来说也很尴尬.

The other way I can think of to solve this is wrap this into a try catch construct which I feel is also rather awkward for such a simple task.

我正在寻找类似的东西:

I am looking for something like:

x = exists(s['mainsnak']['datavalue']['value']['numeric-id'])

如果所有级别都存在,则返回 True.

which returns True if all levels exists.

推荐答案

简而言之,对于 Python,您必须信任它 请求原谅比许可更容易

To be brief, with Python you must trust it is easier to ask for forgiveness than permission

try:
    x = s['mainsnak']['datavalue']['value']['numeric-id']
except KeyError:
    pass

<小时>

答案

这是我处理嵌套字典键的方法:


The answer

Here is how I deal with nested dict keys:

def keys_exists(element, *keys):
    '''
    Check if *keys (nested) exists in `element` (dict).
    '''
    if not isinstance(element, dict):
        raise AttributeError('keys_exists() expects dict as first argument.')
    if len(keys) == 0:
        raise AttributeError('keys_exists() expects at least two arguments, one given.')

    _element = element
    for key in keys:
        try:
            _element = _element[key]
        except KeyError:
            return False
    return True

示例:

data = {
    "spam": {
        "egg": {
            "bacon": "Well..",
            "sausages": "Spam egg sausages and spam",
            "spam": "does not have much spam in it"
        }
    }
}

print 'spam (exists): {}'.format(keys_exists(data, "spam"))
print 'spam > bacon (do not exists): {}'.format(keys_exists(data, "spam", "bacon"))
print 'spam > egg (exists): {}'.format(keys_exists(data, "spam", "egg"))
print 'spam > egg > bacon (exists): {}'.format(keys_exists(data, "spam", "egg", "bacon"))

输出:

spam (exists): True
spam > bacon (do not exists): False
spam > egg (exists): True
spam > egg > bacon (exists): True

它在给定的 element 中循环,以给定的顺序测试每个键.

It loop in given element testing each key in given order.

与我发现的所有 variable.get('key', {}) 方法相比,我更喜欢这个方法,因为它遵循 EAFP.

I prefere this to all variable.get('key', {}) methods I found because it follows EAFP.

除了被调用的函数:keys_exists(dict_element_to_test, 'key_level_0', 'key_level_1', 'key_level_n', ..).至少需要两个参数,元素和一个键,但您可以添加所需的键数.

Function except to be called like: keys_exists(dict_element_to_test, 'key_level_0', 'key_level_1', 'key_level_n', ..). At least two arguments are required, the element and one key, but you can add how many keys you want.

如果您需要使用某种地图,您可以执行以下操作:

If you need to use kind of map, you can do something like:

expected_keys = ['spam', 'egg', 'bacon']
keys_exists(data, *expected_keys)

这篇关于检查字典中是否存在嵌套键的优雅方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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