为什么是 dict.get(key) 而不是 dict[key]?

2022-09-05 01:09:38

今天,我遇到了一种方法,该方法在字典中给定一个键,返回关联的值。dictget

此功能的用途是什么?如果我想在字典中找到与键关联的值,我可以只做,它返回同样的事情:dict[key]

dictionary = {"Name": "Harry", "Age": 17}
dictionary["Name"]
dictionary.get("Name")

答案 1

它允许您在缺少密钥时提供默认值:

dictionary.get("bogus", default_value)

返回(无论你选择它是什么),而default_value

dictionary["bogus"]

会提出一个.KeyError

如果省略,则为 ,使得default_valueNone

dictionary.get("bogus")  # <-- No default specified -- defaults to None

返回就像None

dictionary.get("bogus", None)

愿意。


答案 2

什么是 dict.get() 方法?

如前所述,该方法包含一个指示缺失值的附加参数。从文档中get

get(key[, default])

如果 key 在字典中,则返回 key 的值,否则返回默认值。如果未指定默认值,则默认为 None,以便此方法永远不会引发 .KeyError

例如

>>> d = {1:2,2:3}
>>> d[1]
2
>>> d.get(1)
2
>>> d.get(3)
>>> repr(d.get(3))
'None'
>>> d.get(3,1)
1

在任何地方都有速度改进吗?

如前所述

似乎所有这三种方法现在都表现出相似的性能(在彼此的10%以内),或多或少独立于单词列表的属性。

以前要慢得多,但是现在速度几乎可以与返回默认值的额外优势相媲美。但是为了清除所有查询,我们可以在相当大的列表上进行测试(请注意,测试仅包括查找所有有效键)get

def getway(d):
    for i in range(100):
        s = d.get(i)

def lookup(d):
    for i in range(100):
        s = d[i]

现在使用 timeit 对这两个函数进行计

>>> import timeit
>>> print(timeit.timeit("getway({i:i for i in range(100)})","from __main__ import getway"))
20.2124660015
>>> print(timeit.timeit("lookup({i:i for i in range(100)})","from __main__ import lookup"))
16.16223979

正如我们所看到的,查找比get更快,因为没有函数查找。这可以通过dis来查看

>>> def lookup(d,val):
...     return d[val]
... 
>>> def getway(d,val):
...     return d.get(val)
... 
>>> dis.dis(getway)
  2           0 LOAD_FAST                0 (d)
              3 LOAD_ATTR                0 (get)
              6 LOAD_FAST                1 (val)
              9 CALL_FUNCTION            1
             12 RETURN_VALUE        
>>> dis.dis(lookup)
  2           0 LOAD_FAST                0 (d)
              3 LOAD_FAST                1 (val)
              6 BINARY_SUBSCR       
              7 RETURN_VALUE  

它在哪里有用?

每当您要在查找字典时提供默认值时,它都会很有用。这减少了

 if key in dic:
      val = dic[key]
 else:
      val = def_val

对于一行,val = dic.get(key,def_val)

它在哪里没有用?

每当您要返回一个声明特定密钥不可用时。返回默认值还存在特定默认值也可能是键的风险!KeyError

是否有可能在dict['key']具有类似功能?

是的!我们需要在字典子类中实现__missing__

示例程序可以是

class MyDict(dict):
    def __missing__(self, key):
        return None

一个小小的演示可以是

>>> my_d = MyDict({1:2,2:3})
>>> my_d[1]
2
>>> my_d[3]
>>> repr(my_d[3])
'None'