Привет, Хабр! представляю вашему вниманию перевод статьи «Stop Using Square Bracket Notation to Get a Dictionary’s Value in Python» автора Jonathan Hsu.

Выходим за рамки традиционного метода и защищаем свой код


Словарь — это несортированный набор ключей и значений. Это значит, что:

  • Каждый элемент словаря состоит из термина (ключ) и его определения (значение).
  • Ключи должны быть уникальными для данного словаря — никаких повторений.
  • Ключи в словаре не имеют такого явного порядка расположения, который есть у элементов списка.

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

author = {
   "first_name": "Robinson",
   "last_name": "Crusoe",
   "username": "Friday1719"
}

Традиционный (и небезопасный) способ получения значения из словаря.

При обычном доступе к значению элемента из словаря используются квадратные скобки. При использовании такой записи после имени словаря в квадратных скобках указывается ключ:

author = {
   "first_name": "Robinson",
   "last_name": "Crusoe",
   "username": "Friday1719"
}
print(author['username']) # выведет Friday1719
print(author['middle_initial']) # получим ошибку KeyError: 'middle_initial'

Обратите внимание, что попытка обратиться к значению по ключу, которого нет в словаре, вызовет исключение KeyError. Это может создать серьёзные проблемы, особенно при работе с непредсказуемыми рабочими данными.

Конечно, можно воспользоваться конструкцией try/except или использовать инструкцию if. Но такое повышенное внимание к столь простой операции лишь загромождает код.

author = {}
try:
   print(author['username'])
except KeyError as e:
   print(e) # 'username'

if 'username' in author:
   print(author['username'])

Если у вас за плечами опыт разработки на JavaScript, то вам, возможно, захочется получить значение из словаря с помощью точечной нотации. Но в Python'е это не сработает.

author = {
   "first_name": "Robinson",
   "last_name": "Crusoe",
   "username": "Friday1719"
}
print(author.username)
# AttributeError: 'dict' object has no attribute 'username'

Используем метод get()


Когда вам нужно получить значение из словаря, то самым безопасным способом будет использование метода get(). У этого метода есть два параметра:

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

author = {
   "first_name": "Robinson",
   "last_name": "Crusoe",
   "username": "Friday1719"
}
print(author.get('username')) # выведет  Friday1719
print(author.get('middle_initial', “Monday1917”)) # выведет Monday1917

Если ключ существует в словаре, то метод get() работает точно таким же образом, как и обращение по ключу в квадратных скобках. Зато в случае, когда такого ключа в словаре нет, метод get() вернёт значение по умолчанию, избавив вас от необходимости обрабатывать исключение.

Значением по умолчанию может быть любой допустимый в данном контексте объект. Не забывайте о том, что этот параметр не обязателен. Поэтому, если вы его не укажете явным образом, то при попытке обратиться по несуществующему в словаре ключу, метод get() вернёт объект None.

Используем метод setdefault()


Иногда вам будет нужно не только безопасно получить данные из словаря, но и также безопасно добавить новые данные в словарь. Для этого у словарей есть метод setdefault(). Он имеет те же параметры, что и метод get(), но в отличие от последнего, при обращении к словарю по несуществующему ключу, он не только вернёт переданное по умолчанию значение, но и создаст в словаре новый элемент с этим ключом и переданным значением. Если при обращении к словарю с помощью метода setdefault() передаваемый ключ уже есть в словаре, то данный метод оставит словарь без изменений.

author = {
   "first_name": "Robinson",
   "last_name": "Crusoe",
   "username": "Friday1719"
}

print(author.setdefault('username')) # выведет Friday1719
print(author.setdefault('middle_initial', “Monday”)) # выведет Monday и создаст
# в словаре элемент с ключом 'middle_initial' и значением для этого ключа “Monday”

В примере выше мы видим, что поведение метода setdefault() ничем не отличается от поведения метода get() или от применения квадратных скобок при обращении к словарю по существующему в нём ключу. В случае, если такого ключа в словаре нет, то метод setdefault() не только вернёт в программу значение своего второго аргумента (как и метод get()), но и создаст в словаре элемент с переданными ему ключом и значением. Это поведение метода setdefault() и отличает его от метода get().

Теперь, если выполнить пример выше и вывести элементы словаря, то мы получим такой результат:

print(author)
{
  "first_name": "Robinson",
  "last_name": "Crusoe",
  "username": "Friday1719"
  "middle_initial": "Monday"
}

Применение методов get() и setdefault() является первоклассной техникой при обращении к значениям словаря. Нужно лишь время, чтобы отказаться от старых привычек и начать использовать эту технику на практике.

Если вам нужно только получить значение из словаря, то ваш помощник — метод get().

Если же вам нужно безопасно добавить новое значение в словарь, то вызывайте метод setdefault().