Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Ключи словаря в Python
Ключом словаря может быть любой неизменяемый (immutable) объект, который имеет хеш-значение (hashable). Это один из ключевых аспектов устройства словарей в Python, так как они используют хеш-таблицы для быстрого доступа к значениям.
Допустимые типы ключей
1. Числа (int, float, complex)
d = {}
d[42] = "integer"
d[3.14] = "float"
d[1+2j] = "complex"
print(d) # {42: 'integer', 3.14: 'float', (1+2j): 'complex'}
2. Строки (str)
d = {}
d["name"] = "John"
d["age"] = 30
d["Python"] = "language"
print(d) # {'name': 'John', 'age': 30, 'Python': 'language'}
3. Кортежи (tuple) — если они содержат только hashable элементы
d = {}
d[(1, 2)] = "coordinates"
d[("a", "b", "c")] = "tuple key"
d[(1, (2, 3))] = "nested tuple"
print(d)
4. Логические значения (bool)
d = {True: "yes", False: "no"}
print(d) # {True: 'yes', False: 'no'}
5. None
d = {None: "empty value"}
print(d) # {None: 'empty value'}
6. Frozenset — неизменяемое множество
d = {}
fs = frozenset([1, 2, 3])
d[fs] = "frozen set key"
print(d) # {frozenset({1, 2, 3}): 'frozen set key'}
7. Пользовательские объекты с hash
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
d = {}
p = Point(1, 2)
d[p] = "point"
print(d) # {<Point object>: 'point'}
Недопустимые типы ключей
Список (list)
d = {}
d[[1, 2, 3]] = "list" # TypeError: unhashable type: 'list'
Множество (set)
d = {}
d[{1, 2, 3}] = "set" # TypeError: unhashable type: 'set'
Словарь (dict)
d = {}
d[{"key": "value"}] = "dict" # TypeError: unhashable type: 'dict'
Кортеж со списком внутри
d = {}
d[(1, [2, 3])] = "tuple with list" # TypeError: unhashable type: 'list'
Проверка hashability
from collections.abc import Hashable
print(isinstance(42, Hashable)) # True
print(isinstance("text", Hashable)) # True
print(isinstance([1, 2], Hashable)) # False
print(isinstance({1, 2}, Hashable)) # False
# Или используй hash()
try:
hash([1, 2, 3])
except TypeError as e:
print(f"Not hashable: {e}") # Not hashable: unhashable type: 'list'
Важные особенности
-
Хеш-значение остаётся константным — если объект используется как ключ, его хеш не должен меняться (поэтому строки, числа и кортежи идеальны).
-
Равенство и хеш — если два объекта равны (a == b), их хеш-значения должны быть одинаковыми. Это критично для правильной работы словаря.
-
Производительность — хорошая функция хеша распределяет значения равномерно, что обеспечивает O(1) для поиска ключа.
-
Python 3.7+ — словари сохраняют порядок вставки ключей.
Практический пример
# Счётчик символов в строке
text = "hello world"
char_count = {}
for char in text:
if char in char_count:
char_count[char] += 1
else:
char_count[char] = 1
print(char_count) # {'h': 1, 'e': 1, 'l': 3, 'o': 2, ' ': 1, 'w': 1, 'r': 1, 'd': 1}
# Используя tuple как ключ
locations = {}
locations[(40.7128, -74.0060)] = "New York"
locations[(51.5074, -0.1278)] = "London"
print(locations) # {(40.7128, -74.006): 'New York', (51.5074, -0.1278): 'London'}
Вывод: ключом может быть любой hashable (неизменяемый) тип. Это ограничение существует потому, что словари используют хеш-таблицы для эффективного поиска, а хеш-функция требует стабильных значений.