Почему 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'