Какие типы данных могут быть ключами в словаре (ассоциативном массиве) в Python?

«Какие типы данных могут быть ключами в словаре (ассоциативном массиве) в Python?» — вопрос из категории Основы программирования, который задают на 10% собеседований QA Тестировщик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

Главное правило: Ключ должен быть неизменяемым (immutable) типом.

Допустимые типы ключей (хешируемые и неизменяемые):

  1. Числа: int, float, complex, bool (True/False).
  2. Строки: str.
  3. Кортежи (tuple): Но только если все элементы кортежа сами являются хешируемыми.
  4. frozenset: Неизменяемая версия множества.
  5. bytes.

Недопустимые типы ключей (нехешируемые и изменяемые):

  1. Списки (list).
  2. Словари (dict).
  3. Множества (set).
  4. Большинство пользовательских классов (по умолчанию хешируемы, но могут стать нехешируемыми, если реализуют __eq__ без __hash__ или являются изменяемыми).

Примеры на практике:

# ДОПУСТИМЫЕ ключи:
valid_dict = {
    42: 'integer key',
    3.14: 'float key',
    'name': 'string key',
    (1, 2, 3): 'tuple key',          # Кортеж из чисел
    (1, 'a', (2, 3)): 'complex tuple', # Кортеж с вложенным кортежем
    frozenset([1,2]): 'frozenset key',
    True: 'boolean key'
}
print(valid_dict[(1, 2, 3)])  # Вывод: tuple key

# НЕДОПУСТИМЫЕ ключи (вызовут TypeError: unhashable type):
try:
    invalid_dict = {
        [1, 2]: 'list key',   # Список - ИЗМЕНЯЕМЫЙ
        {1, 2}: 'set key',    # Множество - ИЗМЕНЯЕМОЕ
        {'a': 1}: 'dict key'  # Словарь - ИЗМЕНЯЕМЫЙ
    }
except TypeError as e:
    print(f'Ошибка: {e}')

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