如果字典键不可用,则返回None


488

我需要一种方法来获取字典值(如果它的键存在),或者简单地返回None,如果它不存在。

但是,KeyError如果您搜索不存在的键,Python会引发异常。我知道我可以检查密钥,但是我正在寻找更明确的密钥。None如果密钥不存在,是否有办法返回?


74
只要使用.get(key)的不是[key]
加布

12
dict引发KeyError异常。它不会“返回key_error”。
小檗碱

3
在Python中访问键并捕获异常是完全可以的。它甚至是一种众所周知且经常使用的设计模式。如果改为返回None,则将None作为值存储就变得不可能了,这在某些情况下可能是相关的。
Ber

1
有时,您希望将字典中的“无”条目与缺少的条目视为相同,在这种情况下,可接受的答案似乎可以很好地完成工作。
cib

@贝尔,我已经编辑了问题以弄清楚。您也可以这样做。
törzsmókus

Answers:


811

您可以使用 dict.get()

value = d.get(key)

None如果将返回key is not in d。您还可以提供将返回的其他默认值,而不是None

value = d.get(key, "empty")

47
请注意,None如果键None在dict中显式映射到默认变体的第二个变体仍将返回。如果这不是您想要的,可以使用d.get(key) or "empty"
cib

15
@cib:好点,但解决的办法也有类似的问题-如果该键被映射到任何“falsy”的值(如[]""False0.0或事实上None),那么你的解决方案将始终返回0。如果希望将Nones作为值,则必须if key in d:显式地进行检查。
蒂姆·皮茨克

1
@cib为此欢呼,我无法弄清楚我在这里做错了什么。
wobbily_col

@TimPietzcker-您能解释一下您的答案吗?d.get(key)或“ empty”(如果键被映射到任何“ falsy”值的情况)为“ empty”(如果我没有记错的话)。
MiloMinderbinder

@MiloMinderbinder:"empty"如果key不是有效的键,则返回d。它与key映射到的值无关。
Tim Pietzcker

63

别再奇怪了。它内置在语言中。

    >>>帮助(dict)

    模块内置的类字典帮助:

    类dict(object)
     | dict()->新的空字典
     | dict(mapping)->从映射对象的字典初始化的新字典
     | (键,值)对
    ...
     |  
     | 得到(...)
     | D.get(k [,d])-> D [k]如果D中有k,否则为d。d默认为无。
     |  
    ...

22

采用 dict.get

如果key在字典中,则返回key的值,否则返回默认值。如果未提供default,则默认为None,因此此方法永远不会引发KeyError。


19

您应该使用类中的get()方法dict

d = {}
r = d.get('missing_key', None)

这将导致r == None。如果在字典中找不到键,则get函数将返回第二个参数。


19
您不必None显式地通过。这是默认值。
比约恩博动

18

如果您想要一个更透明的解决方案,则可以继承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

2
@marineau:正如我在对另一个答案的评论中提到的那样,的问题defaultdict是,每当请求一个尚不存在的元素时,它将增加。这并不总是可取的。
比约恩博动

@BjörnPollex到目前为止,这是一种优雅的方法,关于如何扩展此方法以支持任何深度的任何线索?我的意思是说foo['bar']['test']['sss']要返回None而不是例外,经过一段深度后,它开始给予TypeError而不是KeyError
nehem 2015年

@itsneo。您可以构建的整个结构NoneDicts。如果这将在KeyError最里面的对象中发生,这将有所帮助。否则问题是,一旦返回None对象,您将无法再订阅它。一个丑陋的破解方法是返回另一个测试类似的对象None。但是请注意,这可能会导致可怕的错误。
magu_

@BjörnPollex可以更改return dict.get(self, key)return super().get(key)吗?然后,例如,如果我决定使用OrderedDict而不是dict,则不必担心更改多行代码。
伍德

@Wood是的,这实际上要好得多!
比约恩·波莱克斯(BjörnPollex)

12

我通常在这种情况下使用defaultdict。您提供一个不带任何参数的工厂方法,并在看到新键时创建一个值。当您想在新键上返回空列表之类的功能时,它会更有用(请参见示例)。

from collections import defaultdict
d = defaultdict(lambda: None)
print d['new_key']  # prints 'None'

19
的问题defaultdict是,每次请求不存在的元素时,它将保持增长。
比约恩博动

8

您可以使用dict对象的get()方法,就像其他人已经建议的那样。另外,根据您正在执行的操作,您可能可以使用如下try/except套件:

try:
   <to do something with d[key]>
except KeyError:
   <deal with it not being there>

这被认为是处理案件的非常“ Pythonic”的方法。


7

一线解决方案是:

item['key'] if 'key' in item else None

在尝试将字典值添加到新列表并想要提供默认值时,这很有用:

例如。

row = [item['key'] if 'key' in item else 'default_value']

5

就像其他人说的那样,您可以使用get()。

但是要检查密钥,您也可以执行以下操作:

d = {}
if 'keyname' in d:

    # d['keyname'] exists
    pass

else:

    # d['keyname'] does not exist
    pass

我现在看到您已经知道如何执行此操作。我打算删除自己的帖子,但我会将其留给他人参考。
Marek P

4
这种方法通常需要在密钥存在时对其进行两次查找,这可能是该get方法的原因。
martineau 2011年

0

我被python2 vs python3中可能发生的事情吓了一跳。我将根据最终对python3所做的回答。我的目标很简单:检查字典格式的json响应是否给出错误。我的字典称为“令牌”,而我正在寻找的密钥是“错误”。我正在寻找键“错误”,如果不存在,则将其设置为“无”,然后检查其值为“无”,如果是,请继续执行我的代码。如果我确实拥有键“错误”,则将执行else语句。

if ((token.get('error', None)) is None):
    do something

-2

如果可以使用False,则还可以使用hasattr内置功能:

e=dict()
hasattr(e, 'message'):
>>> False
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.