Метод get в Python: работа со словарями без ошибок

Раздел: Основы Python -> Коллекции

Безопасное получение значений из словаря с помощью get

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


contacts = {'Анна': '555-123', 'Иван': '555-456'}
phone = contacts.get('Пётр')
print(phone)  # None
phone = contacts.get('Пётр', 'номер не найден')
print(phone)  # номер не найден
    

Python set list (set и list в python: различия и использование)

None
номер не найден
    

Python пары значений (пары значений в python)

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

Как проверить наличие ключа перед обращением, если метод get по каким-то причинам не подходит?

Можно использовать оператор in в сочетании с условным оператором. Это даёт полный контроль над логикой, но требует больше кода.


contacts = {'Анна': '555-123', 'Иван': '555-456'}
if 'Пётр' in contacts:
    phone = contacts['Пётр']
else:
    phone = 'абонент не найден'
print(phone)
    

Python object get (метод get для объектов в python)

абонент не найден

Python get keys (метод get для словарей в python)

Типичная ошибка: забыть обработать отсутствие ключа и получить KeyError. Проверка через in полностью решает эту проблему, но требует явного разделения кода на две ветви.

Как использовать значение по умолчанию, которое будет вычислено только при необходимости?

Метод get() вычисляет второй аргумент при каждом вызове, даже если ключ существует. Для ленивых вычислений можно воспользоваться defaultdict из модуля collections.


from collections import defaultdict

def default_phone():
    return 'номер отсутствует'

contacts = defaultdict(default_phone, {'Анна': '555-123', 'Иван': '555-456'})
print(contacts['Анна'])      # 555-123
print(contacts['Пётр'])      # номер отсутствует
    

Get index python (метод index в python)

555-123
номер отсутствует
    

Python get methods (методы get в python)

Важно: defaultdict автоматически вставляет ключ со значением по умолчанию при обращении, что может изменить размер словаря. Это не всегда желательно.

Как получить значение с автоматическим созданием записи, если ключ отсутствует, но без изменения словаря при чтении?

Метод setdefault() похож на get, но если ключ отсутствует, он вставляет в словарь пару ключ-значение по умолчанию.


contacts = {'Анна': '555-123'}
phone = contacts.setdefault('Пётр', 'неизвестен')
print(phone)               # неизвестен
print(contacts)            # {'Анна': '555-123', 'Пётр': 'неизвестен'}
    

Python длина списка (длина списка и массива в python)

неизвестен
{'Анна': '555-123', 'Пётр': 'неизвестен'}
    

словарь данных python (словарь данных в python)

Различие с get: setdefault меняет исходный словарь, что в некоторых сценариях (например, при простом чтении) является нежелательным побочным эффектом. Следует выбирать get для безопасного чтения без модификации.

Как безопасно получить значение атрибута объекта, а не элемента словаря?

Встроенная функция getattr(obj, name, default) работает аналогично dict.get, но для атрибутов объектов.


class User:
    def __init__(self, name):
        self.name = name

u = User('Анна')
print(getattr(u, 'name', 'гость'))    # Анна
print(getattr(u, 'age', 18))          # 18
    

типы данных python кортеж (кортеж (tuple) в python)

Анна
18
    

Ошибка: при использовании прямого обращения u.age для отсутствующего атрибута возникает AttributeError. getattr предотвращает это и возвращает значение по умолчанию.

Пример

# 1. Вложенные словари: получение значения из нескольких уровней
config = {
    'database': {
        'host': 'localhost',
        'port': 5432
    },
    'debug': False
}
# Безопасное чтение вложенного ключа с помощью цепочек get
port = config.get('database', {}).get('port', 3306)
print(port)  # 5432

# Когда промежуточный ключ отсутствует
host = config.get('cache', {}).get('host', 'default.host')
print(host)  # default.host
    
5432
default.host
    
Пример

# 2. Использование get с функциями по умолчанию (ленивый вызов)
def make_default():
    print('Функция по умолчанию вызвана')
    return 'default_value'

data = {'key': 'original'}
value = data.get('key', make_default())   # Функция будет вызвана, даже если ключ есть
print(value)  # original

# Чтобы избежать вызова, можно использовать вложенный get или явную проверку
value = data['key'] if 'key' in data else make_default()
    
Функция по умолчанию вызвана
original
    
Пример

# 3. Подсчёт частоты элементов с помощью get (альтернатива collections.Counter)
words = ['яблоко', 'банан', 'яблоко', 'апельсин', 'банан', 'яблоко']
freq = {}
for word in words:
    freq[word] = freq.get(word, 0) + 1
print(freq)  # {'яблоко': 3, 'банан': 2, 'апельсин': 1}
    
{'яблоко': 3, 'банан': 2, 'апельсин': 1}
    
Пример

# 4. get для объектов datetime и других неизменяемых типов
from datetime import date

birthdays = {
    'Анна': date(1995, 5, 10),
    'Иван': date(1990, 12, 3)
}
# По умолчанию возвращается сегодняшняя дата (но get не поддерживает динамическое значение)
# Поэтому используем лямбду вне get
import datetimedefault = date.today()
print(birthdays.get('Пётр', default))  # выведет сегодняшнюю дату (но вычислится сразу)
    
Пример

# 5. Работа с get в списковых включениях (list comprehension)
users = [{'id': 1, 'name': 'Анна'}, {'id': 2}, {'id': 3, 'name': 'Иван'}]
names = [user.get('name', 'Без имени') for user in users]
print(names)  # ['Анна', 'Без имени', 'Иван']
    
['Анна', 'Без имени', 'Иван']
    
Пример

# 6. Безопасное получение с несколькими альтернативами (вложенный get)
settings = {}
# попытка получить значение по трём ключам
value = settings.get('timeout') or settings.get('ttl') or settings.get('expire', 30)
print(value)  # 30
    
30
    
Пример

# 7. Применение get с изменяемыми значениями по умолчанию (осторожно!)
def get_with_list(d, key):
    # Если ключа нет, возвращается один и тот же список при последующих вызовах?
    # На самом деле каждый вызов get создаёт новый список, потому что [] вычисляется заново
    return d.get(key, [])

d = {}
res1 = get_with_list(d, 'a')
res2 = get_with_list(d, 'a')
print(res1 is res2)  # False, каждый раз новый список
    
False
    
Пример

# 8. Использование getatt с объектами для эмуляции словарного get
class Config:
    pass

cfg = Config()
cfg.host = 'localhost'
port = getattr(cfg, 'port', 8080)
print(port)  # 8080
    
8080
    

Методы get в Python - comments

En
Python get methods (python)