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

问题:为什么用dict.get(key)而不是dict [key]?

今天,我遇到了该dict方法get,给定字典中的键,该方法将返回关联的值。

此功能用于什么目的?如果我想找到与字典中的键相关联的值,我可以这样做dict[key],并且它返回相同的内容:

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

Today, I came across the dict method get which, given a key in the dictionary, returns the associated value.

For what purpose is this function useful? If I wanted to find a value associated with a key in a dictionary, I can just do dict[key], and it returns the same thing:

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

回答 0

如果密钥丢失,它允许您提供默认值:

dictionary.get("bogus", default_value)

返回default_value(无论您选择的是什么),而

dictionary["bogus"]

会提出一个KeyError

如果省略,default_value则为None,这样

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

返回None就像

dictionary.get("bogus", None)

将。

It allows you to provide a default value if the key is missing:

dictionary.get("bogus", default_value)

returns default_value (whatever you choose it to be), whereas

dictionary["bogus"]

would raise a KeyError.

If omitted, default_value is None, such that

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

returns None just like

dictionary.get("bogus", None)

would.


回答 1

什么dict.get()方法?

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

get(key[, default])

如果key在字典中,则返回key的值,否则返回默认值。如果未提供default,则默认为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

如我们所见,由于没有函数查找,因此查找比获取更快。可以看出来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说明该特定键不可用时。返回默认值还会带来一个风险,即某个默认值也可能是键!

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

是! 我们需要实施__missing__在dict子类中实现。

一个示例程序可以是

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'

What is the dict.get() method?

As already mentioned the get method contains an additional parameter which indicates the missing value. From the documentation

get(key[, default])

Return the value for key if key is in the dictionary, else default. If default is not given, it defaults to None, so that this method never raises a KeyError.

An example can be

>>> 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

Are there speed improvements anywhere?

As mentioned here,

It seems that all three approaches now exhibit similar performance (within about 10% of each other), more or less independent of the properties of the list of words.

Earlier get was considerably slower, However now the speed is almost comparable along with the additional advantage of returning the default value. But to clear all our queries, we can test on a fairly large list (Note that the test includes looking up all the valid keys only)

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

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

Now timing these two functions using 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

As we can see the lookup is faster than the get as there is no function lookup. This can be seen through 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  

Where will it be useful?

It will be useful whenever you want to provide a default value whenever you are looking up a dictionary. This reduces

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

To a single line, val = dic.get(key,def_val)

Where will it be NOT useful?

Whenever you want to return a KeyError stating that the particular key is not available. Returning a default value also carries the risk that a particular default value may be a key too!

Is it possible to have get like feature in dict['key']?

Yes! We need to implement the __missing__ in a dict subclass.

A sample program can be

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

A small demonstration can be

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

回答 2

get采用第二个可选值。如果字典中不存在指定的键,则将返回此值。

dictionary = {"Name": "Harry", "Age": 17}
dictionary.get('Year', 'No available data')
>> 'No available data'

如果不提供第二个参数,None将返回。

如果您按这种方式使用索引dictionary['Year'],则不存在的键将引发KeyError

get takes a second optional value. If the specified key does not exist in your dictionary, then this value will be returned.

dictionary = {"Name": "Harry", "Age": 17}
dictionary.get('Year', 'No available data')
>> 'No available data'

If you do not give the second parameter, None will be returned.

If you use indexing as in dictionary['Year'], nonexistent keys will raise KeyError.


回答 3

我将举一个使用python抓取Web数据的实际示例,很多时候,您将获得没有值的键,在这些情况下,如果您使用dictionary [‘key’]会出错,而dictionary.get(’key ‘,’return_otherwise’)没问题。

同样,如果您尝试从列表中捕获单个值,我将使用”.join(list)而不是list [0]。

希望能帮助到你。

[编辑]这是一个实际示例:

假设您正在调用一个API,该API返回您需要解析的JOSN文件。第一个JSON如下所示:

{"bids":{"id":16210506,"submitdate":"2011-10-16 15:53:25","submitdate_f":"10\/16\/2011 at 21:53 CEST","submitdate_f2":"p\u0159ed 2 lety","submitdate_ts":1318794805,"users_id":"2674360","project_id":"1250499"}}

第二个JOSN是这样的:

{"bids":{"id":16210506,"submitdate":"2011-10-16 15:53:25","submitdate_f":"10\/16\/2011 at 21:53 CEST","submitdate_f2":"p\u0159ed 2 lety","users_id":"2674360","project_id":"1250499"}}

请注意,第二个JSON缺少“ submitdate_ts”键,这在任何数据结构中都是很正常的。

因此,当您尝试循环访问该键的值时,可以使用以下命令调用它:

for item in API_call:
    submitdate_ts = item["bids"]["submitdate_ts"]

您可以,但是它将给您第二条JSON行的回溯错误,因为密钥根本不存在。

适当的编码方式如下:

for item in API_call:
    submitdate_ts = item.get("bids", {'x': None}).get("submitdate_ts")

{‘x’:None}可以避免第二级出错。当然,如果您执行抓取操作,则可以在代码中内置更多的容错功能。就像首先指定一个if条件

I will give a practical example in scraping web data using python, a lot of the times you will get keys with no values, in those cases you will get errors if you use dictionary[‘key’], whereas dictionary.get(‘key’, ‘return_otherwise’) has no problems.

Similarly, I would use ”.join(list) as opposed to list[0] if you try to capture a single value from a list.

hope it helps.

[Edit] Here is a practical example:

Say, you are calling an API, which returns a JOSN file you need to parse. The first JSON looks like following:

{"bids":{"id":16210506,"submitdate":"2011-10-16 15:53:25","submitdate_f":"10\/16\/2011 at 21:53 CEST","submitdate_f2":"p\u0159ed 2 lety","submitdate_ts":1318794805,"users_id":"2674360","project_id":"1250499"}}

The second JOSN is like this:

{"bids":{"id":16210506,"submitdate":"2011-10-16 15:53:25","submitdate_f":"10\/16\/2011 at 21:53 CEST","submitdate_f2":"p\u0159ed 2 lety","users_id":"2674360","project_id":"1250499"}}

Note that the second JSON is missing the “submitdate_ts” key, which is pretty normal in any data structure.

So when you try to access the value of that key in a loop, can you call it with the following:

for item in API_call:
    submitdate_ts = item["bids"]["submitdate_ts"]

You could, but it will give you a traceback error for the second JSON line, because the key simply doesn’t exist.

The appropriate way of coding this, could be the following:

for item in API_call:
    submitdate_ts = item.get("bids", {'x': None}).get("submitdate_ts")

{‘x’: None} is there to avoid the second level getting an error. Of course you can build in more fault tolerance into the code if you are doing scraping. Like first specifying a if condition


回答 4

目的是如果找不到密钥,则可以提供默认值,这非常有用

dictionary.get("Name",'harry')

The purpose is that you can give a default value if the key is not found, which is very useful

dictionary.get("Name",'harry')

回答 5

此功能用于什么目的?

一种特殊用法是用字典计数。假设您要计算给定列表中每个元素的出现次数。这样做的常见方法是制作一个字典,其中键是元素,值是出现的次数。

fruits = ['apple', 'banana', 'peach', 'apple', 'pear']
d = {}
for fruit in fruits:
    if fruit not in d:
        d[fruit] = 0
    d[fruit] += 1

使用该.get()方法,可以使此代码更紧凑,更清晰:

for fruit in fruits:
    d[fruit] = d.get(fruit, 0) + 1

For what purpose is this function useful?

One particular usage is counting with a dictionary. Let’s assume you want to count the number of occurrences of each element in a given list. The common way to do so is to make a dictionary where keys are elements and values are the number of occurrences.

fruits = ['apple', 'banana', 'peach', 'apple', 'pear']
d = {}
for fruit in fruits:
    if fruit not in d:
        d[fruit] = 0
    d[fruit] += 1

Using the .get() method, you can make this code more compact and clear:

for fruit in fruits:
    d[fruit] = d.get(fruit, 0) + 1

回答 6

使用时要注意的陷阱 .get()

如果字典包含在调用中使用的键,.get()并且其值为None,则该.get()方法将返回None即使提供了默认值。

例如,以下返回None,不是'alt_value'预期的:

d = {'key': None}
d.get('key', 'alt_value')

.get()仅当提供的键不在字典中时,才返回的第二个值,如果该调用的返回值为,则不返回None

A gotcha to be aware of when using .get():

If the dictionary contains the key used in the call to .get() and its value is None, the .get() method will return None even if a default value is supplied.

For example, the following returns None, not 'alt_value' as may be expected:

d = {'key': None}
d.get('key', 'alt_value')

.get()‘s second value is only returned if the key supplied is NOT in the dictionary, not if the return value of that call is None.


回答 7

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

0.总结

与相比dict[key]dict.get查找关键字时提供了一个后备值。

1.定义

get(key [,default]) 4.内置类型-Python 3.6.4rc1文档

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

d = {"Name": "Harry", "Age": 17}
In [4]: d['gender']
KeyError: 'gender'
In [5]: d.get('gender', 'Not specified, please add it')
Out[5]: 'Not specified, please add it'

2.解决的问题。

如果没有default value,则必须编写繁琐的代码来处理此类异常。

def get_harry_info(key):
    try:
        return "{}".format(d[key])
    except KeyError:
        return 'Not specified, please add it'
In [9]: get_harry_info('Name')
Out[9]: 'Harry'
In [10]: get_harry_info('Gender')
Out[10]: 'Not specified, please add it'

作为一种方便的解决方案,dict.get引入了一个可选的默认值,避免了上面不必要的代码。

3.结论

dict.get 如果字典中没有键,则还有一个附加的默认值选项来处理异常

Why dict.get(key) instead of dict[key]?

0. Summary

Comparing to dict[key], dict.get provides a fallback value when looking up for a key.

1. Definition

get(key[, default]) 4. Built-in Types — Python 3.6.4rc1 documentation

Return the value for key if key is in the dictionary, else default. If default is not given, it defaults to None, so that this method never raises a KeyError.

d = {"Name": "Harry", "Age": 17}
In [4]: d['gender']
KeyError: 'gender'
In [5]: d.get('gender', 'Not specified, please add it')
Out[5]: 'Not specified, please add it'

2. Problem it solves.

If without default value, you have to write cumbersome codes to handle such an exception.

def get_harry_info(key):
    try:
        return "{}".format(d[key])
    except KeyError:
        return 'Not specified, please add it'
In [9]: get_harry_info('Name')
Out[9]: 'Harry'
In [10]: get_harry_info('Gender')
Out[10]: 'Not specified, please add it'

As a convenient solution, dict.get introduces an optional default value avoiding above unwiedly codes.

3. Conclusion

dict.get has an additional default value option to deal with exception if key is absent from the dictionary


回答 8

一个不同可能是一个优点,那就是,如果我们正在寻找一个不存在的键,我们将得到None,这与使用方括号表示法不同,在这种情况下,我们将抛出错误:

print(dictionary.get("address")) # None
print(dictionary["address"]) # throws KeyError: 'address'

关于get方法的最后一件很酷的事情是,它接收了一个默认值的附加可选参数,也就是说,如果我们尝试获取学生的分数值,但是该学生没有分数键,我们可以获取改为0。

因此,不要这样做(或类似操作):

score = None
try:
    score = dictionary["score"]
except KeyError:
    score = 0

我们做得到:

score = dictionary.get("score", 0)
# score = 0

One difference, that can be an advantage, is that if we are looking for a key that doesn’t exist we will get None, not like when we use the brackets notation, in which case we will get an error thrown:

print(dictionary.get("address")) # None
print(dictionary["address"]) # throws KeyError: 'address'

Last thing that is cool about the get method, is that it receives an additional optional argument for a default value, that is if we tried to get the score value of a student, but the student doesn’t have a score key we can get a 0 instead.

So instead of doing this (or something similar):

score = None
try:
    score = dictionary["score"]
except KeyError:
    score = 0

We can do this:

score = dictionary.get("score", 0)
# score = 0

回答 9

根据用法应使用此get方法。

例1

In [14]: user_dict = {'type': False}

In [15]: user_dict.get('type', '')

Out[15]: False

In [16]: user_dict.get('type') or ''

Out[16]: ''

例2

In [17]: user_dict = {'type': "lead"}

In [18]: user_dict.get('type') or ''

Out[18]: 'lead'

In [19]: user_dict.get('type', '')

Out[19]: 'lead'

Based on usage should use this get method.

Example1

In [14]: user_dict = {'type': False}

In [15]: user_dict.get('type', '')

Out[15]: False

In [16]: user_dict.get('type') or ''

Out[16]: ''

Example2

In [17]: user_dict = {'type': "lead"}

In [18]: user_dict.get('type') or ''

Out[18]: 'lead'

In [19]: user_dict.get('type', '')

Out[19]: 'lead'