Какими могут быть ключи словарей в Python?

«Какими могут быть ключи словарей в Python?» — вопрос из категории Скриптинг и автоматизация, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

На практике это означает:

  • Можно использовать: Все неизменяемые встроенные типы.
    • int, float, decimal.Decimal
    • str, bytes
    • bool
    • tuple (но только если все его элементы также хешируемы).
    • frozenset
    • None
  • Нельзя использовать: Изменяемые (mutable) типы.
    • list, set, dict
    • Пользовательские классы по умолчанию хешируемы (по их id), но это поведение можно изменить, определив методы __hash__ и __eq__.

Примеры:

# Допустимые ключи
valid_dict = {
    42: 'integer',
    3.14: 'float',
    'name': 'string',
    ('localhost', 8080): 'tuple as key',  # Кортеж из хешируемых элементов
    frozenset([1, 2, 3]): 'frozenset key',
    None: 'None key'
}

# НЕДОПУСТИМЫЕ ключи вызовут TypeError: unhashable type
invalid_attempts = {
    [1, 2]: 'list',   # Список - изменяемый
    {'key': 'val'}: 'dict', # Словарь - изменяемый
    {1, 2}: 'set'     # Множество - изменяемое
}

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