← Назад к вопросам

К каким типам относится ключ словаря в Python

1.0 Junior🔥 151 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Типы ключей словаря в Python

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

Допустимые типы ключей

Ключами словаря могут быть следующие типы данных:

1. Числа (int, float, complex)

# Целые числа
my_dict = {
    1: "один",
    2: "два",
    -5: "минус пять"
}

# Числа с плавающей точкой
temperatures = {
    36.6: "нормально",
    37.2: "небольшая температура",
    39.5: "высокая температура"
}

# Комплексные числа
complex_dict = {
    complex(1, 2): "комплексное число",
    3+4j: "еще комплексное число"
}

2. Строки (str)

Это наиболее распространённый тип ключей:

user_data = {
    "name": "Иван",
    "email": "ivan@example.com",
    "age": 30,
    "city": "Москва"
}

# Пустая строка тоже валидный ключ
empty_string_dict = {
    "": "пустая строка в качестве ключа"
}

3. Кортежи (tuple)

Только неизменяемые кортежи (которые не содержат изменяемые элементы):

# Кортежи из простых типов
coordinates = {
    (0, 0): "начало координат",
    (1, 2): "точка A",
    (3, 4): "точка B"
}

# Вложенные кортежи
complex_key = {
    (1, (2, 3)): "вложенный кортеж",
    (("a", "b"), ("c", "d")): "кортеж из кортежей"
}

# ❌ Этот пример НЕ работает — кортеж содержит список!
# invalid = {(1, [2, 3]): "ошибка"} # TypeError: unhashable type: 'list'

4. Boolean (bool)

features = {
    True: "включено",
    False: "отключено"
}

# Важно: True и 1 — это один и тот же ключ для словаря!
# False и 0 — это тоже один и тот же ключ
test_dict = {True: "значение1"}
test_dict[1] = "значение2"  # Перезапишет значение для True
print(test_dict)  # {True: "значение2"}

5. None

config = {
    None: "значение по умолчанию",
    "debug": True,
    "timeout": 30
}

6. Замороженные множества (frozenset)

group_members = {
    frozenset(["Alice", "Bob"]): "группа 1",
    frozenset(["Charlie", "David"]): "группа 2"
}

Недопустимые типы ключей

❌ Изменяемые типы

# Список
my_dict = {[1, 2, 3]: "значение"}  # TypeError: unhashable type: 'list'

# Словарь
my_dict = {{"a": 1}: "значение"}  # TypeError: unhashable type: 'dict'

# Множество (set)
my_dict = {{1, 2, 3}: "значение"}  # TypeError: unhashable type: 'set'

Почему работает именно так?

Хеширование — это механизм быстрого поиска ключей в словаре:

# Python вычисляет хеш ключа
hash("hello")      # некое целое число
hash(42)           # некое целое число
hash((1, 2))       # некое целое число

# ❌ Изменяемые объекты нельзя хешировать
hash([1, 2, 3])    # TypeError: unhashable type: 'list'
hash({"a": 1})     # TypeError: unhashable type: 'dict'

Правило: ключ должен быть hashable (иметь метод __hash__) и immutable (неизменяемый).

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

def can_be_key(obj):
    try:
        hash(obj)
        return True
    except TypeError:
        return False

print(can_be_key("hello"))      # True
print(can_be_key((1, 2)))       # True
print(can_be_key([1, 2]))       # False
print(can_be_key({"a": 1}))     # False
print(can_be_key(frozenset([1, 2])))  # True

Кастомные классы как ключи

Вы можете использовать объекты собственных классов в качестве ключей, если они неизменяемы:

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __hash__(self):
        return hash((self.x, self.y))
    
    def __eq__(self, other):
        return isinstance(other, Point) and self.x == other.x and self.y == other.y

# Теперь Point может быть ключом
points = {
    Point(1, 2): "точка A",
    Point(3, 4): "точка B"
}

Резюме

Допустимые ключи: числа, строки, кортежи (без изменяемых элементов), boolean, None, frozenset, и кастомные неизменяемые объекты.

Недопустимые ключи: списки, словари, множества, и другие изменяемые типы.

Ключевое требование: ключ должен быть hashable и immutable.

К каким типам относится ключ словаря в Python | PrepBro