Python 检查字典键是否存在并具有值的有效方法

Python 检查字典键是否存在并具有值的有效方法,python,dictionary,key-value,Python,Dictionary,Key Value,假设有一本字典是这样的: d = {"key1": "value1", "key2": {"key3": "value3"}} if 'key2' in d: if d['key2']: if 'key3' in d['key2']: value = d['key2']['key3'] 字典可能包含也可能不包含键2,键2也可能为空。所以为了得到v

假设有一本字典是这样的:

d = {"key1": "value1", "key2": {"key3": "value3"}}
if 'key2' in d:
    if d['key2']:
        if 'key3' in d['key2']:
            value = d['key2']['key3']
字典可能包含也可能不包含键2,键2也可能为空。所以为了得到value3,我需要检查key2及其值是否存在非空值,这同样适用于key3

现在显而易见的愚蠢解决方案是这样的:

d = {"key1": "value1", "key2": {"key3": "value3"}}
if 'key2' in d:
    if d['key2']:
        if 'key3' in d['key2']:
            value = d['key2']['key3']

现在,我想知道是否有一个更简单的解决方案,这样我就不必连续编写3个ifs了。

一种方法是预测失败并抓住它:

try:
    value = d['key2']['key3']
except (KeyError, TypeError):
    pass
不要用类型的名称来调用变量,这是一种不好的做法,我已将其重命名为d

KeyError捕捉到丢失的键,TypeError捕捉到试图索引非dict的内容

如果您认为这种失败很常见,那么这可能并不理想,因为尝试会有一点开销。。除了街区

在这种情况下,尽管我写的是:

if 'key2' in d and d['key2'] and 'key3' in d['key2']:
    value = d['key2']['key3']
或者更清楚一点:

if 'key2' in d and isinstance(d['key2'], dict) and 'key3' in d['key2']:
    value = d['key2']['key3']
如果您将要为else部分中的值分配其他值,例如None,您还可以考虑:

value = d['key2']['key3'] if 'key2' in d and d['key2'] and 'key3' in d['key2'] else None
    

一种方法是预测失败并抓住它:

try:
    value = d['key2']['key3']
except (KeyError, TypeError):
    pass
不要用类型的名称来调用变量,这是一种不好的做法,我已将其重命名为d

KeyError捕捉到丢失的键,TypeError捕捉到试图索引非dict的内容

如果您认为这种失败很常见,那么这可能并不理想,因为尝试会有一点开销。。除了街区

在这种情况下,尽管我写的是:

if 'key2' in d and d['key2'] and 'key3' in d['key2']:
    value = d['key2']['key3']
或者更清楚一点:

if 'key2' in d and isinstance(d['key2'], dict) and 'key3' in d['key2']:
    value = d['key2']['key3']
如果您将要为else部分中的值分配其他值,例如None,您还可以考虑:

value = d['key2']['key3'] if 'key2' in d and d['key2'] and 'key3' in d['key2'] else None
    
您可以使用默认值的.get:

val = d.get("key2", {}).get("key3", None)  # <-- you can put something else instead of `None`, this value will return if key2 or key3 doesn't exist
您可以使用默认值的.get:

val = d.get("key2", {}).get("key3", None)  # <-- you can put something else instead of `None`, this value will return if key2 or key3 doesn't exist

谢谢你的回答!我通常不会根据数据类型进行变量命名。我只是想做个愚蠢的例子。原来是很愚蠢的:也可以考虑@和Reksisty的建议-使用。GET是一个干净的方式提供一个安全的默认。我最终解决了Test-catch语句。我一直在寻找一种干净的方法来实现这一点,但如果它有效,为什么要修复它呢?这很公平-只要记住,如果您的代码需要快速连续执行数千或数百万次,那么有一些解决方案可能会执行得更好。感谢您的回答!我通常不会根据数据类型进行变量命名。我只是想做个愚蠢的例子。原来是很愚蠢的:也可以考虑@和Reksisty的建议-使用。GET是一个干净的方式提供一个安全的默认。我最终解决了Test-catch语句。我一直在寻找一种干净的方法来实现这一点,但如果它有效,为什么要修复它呢?这很公平——请记住,如果您的代码需要快速连续执行数千或数百万次,那么有一些解决方案可能会执行得更好。