ChatGPT解决这个技术问题 Extra ChatGPT

如果字典键不可用,则返回默认值

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

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

只需使用 .get(key) 而不是 [key]
在 Python 中访问密钥并捕获异常是完全可以的。它甚至是一种众所周知且经常使用的设计模式。如果您返回 None ,则无法将 None 存储为值,这在某些情况下可能是相关的。
有时您想将字典中的“无”条目和丢失的条目视为相同,在这种情况下,接受的答案似乎可以很好地完成工作。

T
Tim Pietzcker

您可以使用 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:好点,但解决方案有一个类似的问题 - 如果键映射到任何“虚假”值(如 []""False0.0 或确实 None),那么您的解决方案将始终返回 0。如果您期望 None 作为值,则必须明确执行 if key in d: 检查。
@cib 为此欢呼,我无法弄清楚我在这里做错了什么。
@TimPietzcker - 你能解释一下你的答案吗?如果我没记错的话,d.get(key) 或“空”如果键被映射到任何“虚假”值,则为“空”。
@MiloMinderbinder:如果 key 不是 d 中的有效键,则返回 "empty"。它与映射到的值 key 无关。
J
John La Rooy

不用怀疑了。它内置在语言中。

>>> help(dict)

    Help on class dict in module builtins:

    class dict(object)
     |  dict() -> new empty dictionary
     |  dict(mapping) -> new dictionary initialized from a mapping object's
     |      (key, value) pairs
    ...
     |  
     |  get(...)
     |      D.get(k[,d]) -> D[k] if k in D, else d.  d defaults to None.
     |  
    ...

R
RWC

使用dict.get

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


E
Evhz

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

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

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


您不必显式传递 None。这是默认设置。
B
Björn Pollex

如果您想要一个更透明的解决方案,您可以继承 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 对象,您将无法再订阅它。一个丑陋的 hack 是返回另一个像 None 测试的对象。但是请注意,这可能会导致可怕的错误。
@BjörnPollex 可以将 return dict.get(self, key) 更改为 return super().get(key) 吗?然后,如果我决定使用 OrderedDict 而不是 dict,例如,我不必担心更改多行代码。
@Wood 是的,那实际上会更好!
A
Asclepius

对于这种情况,我通常使用 defaultdict。您提供一个不带参数的工厂方法,并在看到新键时创建一个值。当您想在新键 (see the examples) 上返回空列表之类的内容时,它会更有用。

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

defaultdict 的问题是每次请求不存在的元素时它都会不断增长。
m
martineau

正如其他人已经建议的那样,您可以使用 dict 对象的 get() 方法。或者,根据您正在做什么,您也许可以使用这样的 try/except 套件:

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

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


我认为这会违反“显式而不是隐式”的原则,并使意图不清楚。更不用说脆弱性和冗长了。
@Haroldo_OK:我不能不同意,这非常明确。
i
imapotatoe123

单线解决方案是:

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

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

例如。

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

M
Marek P

正如上面其他人所说,您可以使用 get()。

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

d = {}
if 'keyname' in d:

    # d['keyname'] exists
    pass

else:

    # d['keyname'] does not exist
    pass

我现在看到您已经知道如何做到这一点。我打算删除我的帖子,但我会把它留给其他人参考。
这种方法通常需要在密钥存在时对其进行两次查找,这可能是 get 方法的原因。
e
eaydin

对于那些对嵌套字典使用 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


F
FastGTR

我对 python2 与 python3 中可能发生的事情感到震惊。我将根据我最终为 python3 所做的事情来回答它。我的目标很简单:检查字典格式的 json 响应是否出错。我的字典被称为“令牌”,我正在寻找的密钥是“错误”。我正在寻找关键的“错误”,如果它不存在将其设置为 None,那么检查该值是否为 None,如果是,请继续我的代码。如果我确实有键“错误”,则 else 语句将处理。

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

V
Varmilo

您可以使用 try-except 块

try:
    value = dict['keyname']

except IndexError:
    value = None

A
Aditya

d1={"一":1,"二":2,"三":3} d1.get("四")

如果您将运行此代码,则不会出现“Keyerror”,这意味着您可以使用“dict.get()”来避免错误并执行您的代码


正如目前所写的那样,您的答案尚不清楚。请edit添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。您可以找到有关如何写出好答案的更多信息in the help center
T
Thickycat

如果你有一个更复杂的需求,相当于缓存,这个类可能会派上用场:

class Cache(dict):
    """ Provide a dictionary based cache

        Pass a function to the constructor that accepts a key and returns
        a value.  This function will be called exactly once for any key
        required of the cache.
    """

    def __init__(self, fn):
        super()
        self._fn = fn

    def __getitem__(self, key):
        try:
            return super().__getitem__(key)
        except KeyError:
            value = self[key] = self._fn(key)
            return value

构造函数采用一个用键调用的函数,并应返回字典的值。然后下次从字典中存储和检索该值。像这样使用它...

def get_from_database(name):
    # Do expensive thing to retrieve the value from somewhere
    return value

answer = Cache(get_from_database)
x = answer(42)   # Gets the value from the database
x = answer(42)   # Gets the value directly from the dictionary

E
Evhz

如果您可以使用 False 做到这一点,那么还有 hasattr 内置函数:

e=dict()
hasattr(e, 'message'):
>>> False

请不要这样做,认为最受好评