如果字典键不可用,则返回 None
Posted
技术标签:
【中文标题】如果字典键不可用,则返回 None【英文标题】:Return a default value if a dictionary key is not available 【发布时间】:2011-09-02 02:42:05 【问题描述】:如果它的键存在,我需要一种方法来获取字典值,或者如果不存在,则简单地返回None
。
但是,如果您搜索不存在的键,Python 会引发KeyError
异常。我知道我可以检查密钥,但我正在寻找更明确的东西。如果密钥不存在,有没有办法只返回None
?
【问题讨论】:
只需使用.get(key)
而不是[key]
在 Python 中访问密钥并捕获异常是完全可以的。它甚至是一种众所周知且经常使用的设计模式。如果您返回 None ,则无法将 None 存储为值,这在某些情况下可能是相关的。
有时您希望将字典中的“无”条目和缺失的条目一视同仁,在这种情况下,接受的答案似乎可以很好地完成工作。
【参考方案1】:
使用dict.get
如果键在字典中,则返回键的值,否则返回默认值。如果未给出默认值,则默认为 None,因此此方法永远不会引发 KeyError。
【讨论】:
【参考方案2】:您应该使用dict
类中的get()
方法
d =
r = d.get('missing_key', None)
这将导致r == None
。如果在字典中没有找到键,get 函数返回第二个参数。
【讨论】:
您不必明确传递None
。这是默认设置。【参考方案3】:
您可以使用dict.get()
value = d.get(key)
如果key is not in d
,它将返回None
。你也可以提供一个不同的默认值,而不是None
:
value = d.get(key, "empty")
【讨论】:
请注意,如果键在字典中显式映射到None
,则具有默认回退的第二个变体仍将返回None
。如果这不是您想要的,您可以使用 d.get(key) or "empty"
之类的东西。
@cib:好点,但解决方案有一个类似的问题 - 如果密钥映射到任何“虚假”值(如[]
、""
、False
、0.0
或者确实是None
),那么您的解决方案将始终返回0
。如果您期望 None
s 作为值,则必须明确执行 if key in d:
检查。
@cib 为之欢呼,我无法弄清楚我在这里做错了什么。
@TimPietzcker - 你能解释一下你的答案吗?如果我没记错的话,d.get(key) 或“空”如果键被映射到任何“虚假”值,则为“空”。
@MiloMinderbinder:如果key
不是d
中的有效键,则返回"empty"
。它与 key
映射到的值无关。【参考方案4】:
如果你想要一个更透明的解决方案,你可以继承 dict
来获得这种行为:
class NoneDict(dict):
def __getitem__(self, key):
return dict.get(self, key)
>>> foo = NoneDict([(1,"asdf"), (2,"qwerty")])
>>> foo[1]
'asdf'
>>> foo[2]
'qwerty'
>>> foo[3] is None
True
【讨论】:
@marineau:正如我在对另一个答案的评论中提到的,defaultdict
的问题在于,每次请求尚未包含的元素时,它都会增长。这并不总是可取的。
@BjörnPollex 这是迄今为止最优雅的一个,关于如何扩展它以支持任何深度的任何线索?我的意思是让foo['bar']['test']['sss']
返回None
而不是异常,在一个深度之后它开始给出TypeError
而不是KeyError
@itsneo。您可以构建NoneDicts
的整个结构。如果KeyError
发生在最里面的对象中,这将有所帮助。否则问题是,一旦你返回一个None
对象,你就不能再订阅它了。一个丑陋的技巧是返回另一个像None
这样测试的对象。但是请注意,这可能会导致可怕的错误。
@BjörnPollex 可以将return dict.get(self, key)
更改为return super().get(key)
吗?然后,如果我决定使用 OrderedDict 而不是 dict,例如,我不必担心更改多行代码。
@Wood 是的,那实际上会更好!【参考方案5】:
正如上面其他人所说,您可以使用 get()。
但要检查密钥,您也可以这样做:
d =
if 'keyname' in d:
# d['keyname'] exists
pass
else:
# d['keyname'] does not exist
pass
【讨论】:
我现在看到您已经知道如何执行此操作了。我打算删除我的帖子,但我会把它留给其他人参考。 这种方法通常需要在key存在时查找两次,这可能是get
方法的原因。【参考方案6】:
对于这种情况,我通常使用defaultdict。您提供一个工厂方法,它不接受任何参数,并在看到新键时创建一个值。当您想在新键 (see the examples) 上返回空列表之类的内容时,它会更有用。
from collections import defaultdict
d = defaultdict(lambda: None)
print d['new_key'] # prints 'None'
【讨论】:
defaultdict
的问题是每次请求不存在的元素时它都会不断增长。【参考方案7】:
不要再怀疑了。它内置在语言中。
>>> 帮助(字典) 关于内置模块中的类 dict 的帮助: 类字典(对象) | dict() -> 新的空字典 | dict(mapping) -> 从映射对象初始化的新字典 | (键,值)对 ... | |得到(...) | D.get(k[,d]) -> D[k] 如果 k 在 D 中,否则 d。 d 默认为无。 | ...【讨论】:
【参考方案8】:您可以使用dict
对象的get()
方法,正如其他人已经建议的那样。或者,根据您正在做什么,您也许可以像这样使用try/except
套件:
try:
<to do something with d[key]>
except KeyError:
<deal with it not being there>
这被认为是处理案件的一种非常“Pythonic”的方法。
【讨论】:
【参考方案9】:如果你可以使用False
,那么还有hasattr内置函数:
e=dict()
hasattr(e, 'message'):
>>> False
【讨论】:
【参考方案10】:单行解决方案是:
item['key'] if 'key' in item else None
这在尝试将字典值添加到新列表并希望提供默认值时很有用:
例如。
row = [item['key'] if 'key' in item else 'default_value']
【讨论】:
【参考方案11】:python2 与 python3 中的可能性让我大吃一惊。我将根据我最终为 python3 所做的事情来回答它。我的目标很简单:检查字典格式的 json 响应是否出错。我的字典被称为“令牌”,我正在寻找的密钥是“错误”。我正在寻找关键的“错误”,如果它不存在将其设置为 None,那么检查该值是否为 None,如果是,请继续我的代码。如果我确实有键“错误”,则 else 语句将处理。
if ((token.get('error', None)) is None):
do something
【讨论】:
【参考方案12】:对于那些对嵌套字典使用dict.get
技术的人,您可以将默认返回值设置为空字典,而不是显式检查字典的每一层,或者扩展dict
类,除了输出-最水平。这是一个例子:
my_dict = 'level_1':
'level_2':
'level_3': 'more_data'
result = my_dict.get('level_1', ).get('level_2', ).get('level_3')
# result -> 'more_data'
none_result = my_dict.get('level_1', ).get('what_level', ).get('level_3')
# none_result -> None
警告:请注意,此技术仅适用于预期键的值是字典的情况。如果字典中确实存在键 what_level
,但它的值是字符串或整数等,那么它会引发 AttributeError
。
【讨论】:
以上是关于如果字典键不可用,则返回 None的主要内容,如果未能解决你的问题,请参考以下文章
Python 字典(Dictionary) setdefault()方法