Как устроен словарь в Python

Python Middle Без компании
Как устроен словарь в Python
Ответы
**Словарь в Python — это хеш-таблица**. **1. Основная идея: Хеш-таблица** Словарь реализован как **хеш-таблица** (hash table). Это структура данных, которая для быстрого доступа к значению использует **хеш-функцию** ключа. **Принцип работы:** - Когда вы добавляете пару `key: value`, Python вычисляет **хеш** ключа (`hash(key)`). - На основе этого хеша вычисляется **индекс ячейки** (слота) в памяти, куда будет помещено значение. - При поиске значения по ключу (`my_dict[key]`) Python снова вычисляет хеш ключа, находит нужный слот и мгновенно возвращает значение. Это обеспечивает среднюю **сложность O(1)** для операций вставки, удаления и поиска, что очень эффективно. **2. Как разрешаются коллизии (конфликты хешей)** Что если два разных ключа имеют одинаковый хеш? (`hash(key1) == hash(key2)`). Это называется **коллизией**. Современные версии Python (начиная с ~3.6) используют эффективный алгоритм для разрешения коллизий, который сочетает в себе: **- Открытая адресация**: Если вычисленный слот уже занят другим ключом, алгоритм ищет *следующий свободный* слот по определенной формуле ( probing ). **- Компактное представление**: Сами пары "ключ-значение" хранятся в отдельном, плотно заполненном массиве. А хеш-таблица на самом деле хранит **индексы** этого массива. **3. Изменение размера (Resizing)** Что происходит, когда словарь растет и свободных слотов становится мало? - Python динамически **увеличивает размер** внутренней хеш-таблицы (например, в 2 раза). - Происходит **rehashing** — все существующие пары ключ-значение перераспределяются по новым слотам на основе их хешей. Это относительно дорогая операция, но она происходит не при каждом добавлении элемента, а только при достижении определенного порога заполненности. Это гарантирует, что средняя производительность остаётся O(1). **4. Порядок элементов** **Важное изменение в Python 3.7+:** Словари **сохраняют порядок** добавления элементов. Это не просто фича, а прямое следствие описанного выше компактного представления. Так как пары ключ-значение хранятся в плотном массиве в порядке добавления, то при итерации словарь просто проходит по этому массиву. В Python 3.6 это было особенностью реализации, а начиная с Python 3.7 это официальная гарантия языка. **5. Требования к ключам** Ключами словаря могут быть только **хешируемые** (immutable) объекты. **- Хешируемые**: `int`, `float`, `str`, `tuple`, `frozenset`. **- Нехешируемые** (не могут быть ключами): `list`, `dict`, `set`. Это требование вытекает из принципа работы: для размещения значения в таблице нужно вычислить стабильный хеш ключа. Если ключ изменяемый (мутабельный), его хеш может измениться, и тогда найти ранее сохраненное значение станет невозможно. ``` # Работает my_dict = {('a', 'b'): 1} # tuple - неизменяемый # Вызовет ошибку TypeError: unhashable type my_dict = {['a', 'b']: 1} # list - изменяемый ``` ###