Почему dict.get(key) вместо dict [key]?

Сегодня я наткнулся на метод dict get, который, учитывая ключ в словаре, возвращает связанное значение.

С какой целью эта функция полезна? Если бы я хотел найти значение, связанное с ключом в словаре, я могу просто сделать dict[key], и он возвращает то же самое:

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

Ответ 1

Он позволяет указать значение по умолчанию, если отсутствует ключ:

dictionary.get("bogus", default_value)

возвращает default_value (что бы вы ни выбрали), тогда как

dictionary["bogus"]

поднимет a KeyError.

Если опущено, default_value - None, так что

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

возвращает None точно так же, как

dictionary.get("bogus", None)

будет.

Ответ 2

What is the dict.get() method?

Как уже упоминалось, метод get содержит дополнительный параметр, который указывает пропущенное значение. Из документации

get(key[, default])

Возвращает значение для ключа, если ключ находится в словаре, иначе по умолчанию. Если значение по умолчанию не задано, по умолчанию используется значение Нет, поэтому этот метод никогда не вызывает значение 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

Are there speed improvements anywhere?

Как уже упоминалось здесь,

Похоже, что все три подхода в настоящее время демонстрируют одинаковую производительность (в пределах примерно 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  

Where will it be useful?

Это будет полезно всякий раз, когда вы хотите указать значение по умолчанию при поиске в словаре. Это уменьшает

 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'

Ответ 3

get принимает второе необязательное значение. Если указанный ключ не существует в вашем словаре, это значение будет возвращено.

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

Если вы не укажете второй параметр, возвращается None.

Если вы используете индексирование как в dictionary['Year'], несуществующие клавиши будут поднимать KeyError.

Ответ 4

Я дам практический пример в очистке веб-данных с помощью python, много раз, когда вы получите ключи без значений, в тех случаях вы получите ошибки, если используете словарь ['key'], тогда как dictionary.get('key', 'return_otherwise') не имеет проблем.

Аналогично, я бы использовал '.join(list) в отличие от списка [0], если вы попытаетесь захватить одно значение из списка.

надеюсь, что это поможет.

[Изменить] Вот пример:

Скажем, вы вызываете 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

Ответ 5

Цель состоит в том, что вы можете указать значение по умолчанию, если ключ не найден, что очень полезно

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

Ответ 6

С какой целью эта функция полезна?

Одно конкретное использование подсчитывается со словарем. Предположим, вы хотите подсчитать количество вхождений каждого элемента в данный список. Обычный способ сделать это - сделать словарь, где ключи - это элементы, а значения - количество вхождений.

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

Ответ 7

Почему dict.get(key) вместо dict [key]?

0. Резюме

Сравнивая с dict[key], dict.get обеспечивает резервное значение при поиске ключа.

1. Определение

get (key [, default]) 4. Встроенные типы - документация Python 3.6.4rc1

Возвращает значение для ключа, если ключ находится в словаре, иначе по умолчанию. Если значение по умолчанию не задано, по умолчанию оно равно 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 имеет дополнительную опцию по умолчанию для dict.get исключения, если ключ отсутствует в словаре

Ответ 8

Нужно знать об этом при использовании .get():

Если в словаре содержится ключ, используемый при вызове .get(), и его значение равно None, .get() вернет None, даже если указано второе значение.

Например, следующее возвращает None, а не "alt_value", как можно было ожидать:

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

Второе значение .get() возвращается только в том случае, если введенный ключ НЕ находится в словаре, а не если возвращаемое значение этого вызова - None.

Ответ 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'