Python dict: полное руководство по словарям

Раздел: Типы данных -> Словари и отображения

Словарь dict: основные концепции

Словарь (dict) - это встроенный тип данных Python, предназначенный для хранения пар “ключ-значение”. Ключи обязаны быть неизменяемыми (хэшируемыми) объектами: числа, строки, кортежи. Значения могут быть любыми. Словари реализованы как хеш-таблицы, что обеспечивает быстрый доступ по ключу.

Как создать словарь и работать с ним базово?

Самый распространенный способ - литерал {} с перечислением пар через запятую.

student = {
    "name": "Иван",
    "group": "ПИ-21",
    "grades": [5, 4, 5]
}

Python dict (словарь dict в python)

Доступ к значениям - по ключу в квадратных скобках. Если ключа нет, возникает KeyError. Для безопасного доступа применяется dict.get(key, default).

print(student["name"])        # Иван
print(student.get("age", 0))  # 0 (ключа нет)
Частая ошибка: забыть проверить наличие ключа, что приводит к исключению. Решение: использовать get() или блок try/except.

Изменение и добавление элементов выполняется присваиванием:

student["group"] = "ПИ-22"   # изменение
student["city"] = "Москва"   # добавление

Удаление - оператор del или метод pop():

del student["grades"]
removed = student.pop("city", None)

Как создать словарь с помощью конструктора dict()?

Конструктор принимает различные источники данных: список кортежей, именованные аргументы, другой словарь.

# Из списка пар
pairs = [("x", 10), ("y", 20)]
d1 = dict(pairs)  # {'x': 10, 'y': 20}

# Из именованных аргументов
d2 = dict(a=1, b=2, c=3)  # {'a': 1, 'b': 2, 'c': 3}

# Копирование
original = {"key": "value"}
copy_dict = dict(original)  # поверхностная копия
Поверхностное копирование не копирует вложенные объекты. Для глубокого копирования применяется copy.deepcopy().

Как объединить несколько словарей?

Метод update() добавляет пары из другого словаря или итерируемого объекта, перезаписывая существующие ключи. В Python 3.9+ доступен оператор | для слияния.

base = {"a": 1, "b": 2}
extra = {"b": 3, "c": 4}
base.update(extra)  # base стал {'a': 1, 'b': 3, 'c': 4}

# Слияние без изменения исходных
merged = {**base, **extra}  # или base | extra (Python 3.9+)

Как получить все ключи, значения или пары?

Методы keys(), values(), items() возвращают представления (view), которые динамически отражают изменения словаря.

d = {"one": 1, "two": 2, "three": 3}
print(list(d.keys()))   # ['one', 'two', 'three']
print(list(d.values())) # [1, 2, 3]
print(list(d.items()))  # [('one', 1), ('two', 2), ('three', 3)]

Как проверить наличие ключа или значения?

Оператор in проверяет наличие ключа. Для проверки значения - in по values().

if "one" in d:
    print("Ключ есть")
if 1 in d.values():
    print("Значение есть")

Как удалить все элементы или конкретный?

Метод clear() очищает словарь. pop(key, default) удаляет ключ и возвращает значение или default, если ключа нет. popitem() удаляет и возвращает последнюю добавленную пару (в Python 3.7+).

d.clear()
print(d)  # {}

d = {"x": 10, "y": 20}
val = d.pop("x", None)   # val = 10, d = {"y": 20}
last = d.popitem()       # ('y', 20), d = {}

Как использовать setdefault для задания значения по умолчанию?

Метод setdefault(key, default) возвращает значение по ключу, если ключ существует, иначе вставляет default и возвращает его. Удобно для подсчета или группировки.

counts = {}
word = "apple"
counts[word] = counts.get(word, 0) + 1
# Альтернатива с setdefault:
counts.setdefault(word, 0)
counts[word] += 1

Типичные проблемы и их решения

  • KeyError при обращении к отсутствующему ключу. Применяется get() или setdefault().
  • TypeError: unhashable type при попытке использовать изменяемый объект (список, словарь) в качестве ключа. Преобразование в кортеж или строку.
  • Изменение словаря во время итерации. Нельзя добавлять или удалять элементы при переборе циклом for k in d:. Создается копия ключей: for k in list(d.keys()):.
  • Порядок элементов. В Python 3.7+ словари сохраняют порядок вставки. В более старых версиях порядок не гарантирован. Для упорядоченного словаря применяется OrderedDict из модуля collections.

Продвинутые примеры и нестандартные приёмы

defaultdict для автоматической инициализации

Пример
from collections import defaultdict

word_counts = defaultdict(int)
words = ["a", "b", "a", "c", "b", "b"]
for w in words:
    word_counts[w] += 1
print(dict(word_counts))
{'a': 2, 'b': 3, 'c': 1}

Counter для подсчета элементов

Пример
from collections import Counter

letters = Counter("abracadabra")
print(letters)
print(letters.most_common(2))
Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})
[('a', 5), ('b', 2)]

Dict comprehension с условием

Пример
numbers = [1, 2, 3, 4, 5]
# Словарь квадратов только для четных чисел
even_squares = {x: x**2 for x in numbers if x % 2 == 0}
print(even_squares)
{2: 4, 4: 16}

Объединение словарей оператором | и |=

Пример
d1 = {"a": 1, "b": 2}
d2 = {"b": 3, "c": 4}

# Новый словарь
merged = d1 | d2
print(merged)

# Изменение существующего (Python 3.9+)
d1 |= d2
print(d1)
{'a': 1, 'b': 3, 'c': 4}
{'a': 1, 'b': 3, 'c': 4}

Безопасный доступ к вложенным словарям

Пример
data = {"user": {"name": "Alice", "address": {"city": "Moscow"}}}
# Обычный доступ с риском KeyError
# city = data["user"]["address"]["city"]
# Безопасный через цепочку get
city = data.get("user", {}).get("address", {}).get("city", None)
print(city)
Moscow

Сортировка словаря по значениям

Пример
scores = {"Alice": 90, "Bob": 85, "Charlie": 95}
# Сортировка по значениям (по возрастанию)
sorted_items = sorted(scores.items(), key=lambda x: x[1])
print(dict(sorted_items))
# По убыванию
sorted_desc = sorted(scores.items(), key=lambda x: x[1], reverse=True)
print(dict(sorted_desc))
{'Bob': 85, 'Alice': 90, 'Charlie': 95}
{'Charlie': 95, 'Alice': 90, 'Bob': 85}

Мемоизация (кэширование) с помощью словаря

Пример
def factorial(n, cache={}):
    if n in cache:
        return cache[n]
    if n <= 1:
        return 1
    cache[n] = n * factorial(n-1)
    return cache[n]

print(factorial(10))
3628800

Преобразование двух списков в словарь

Пример
keys = ["name", "age", "city"]
values = ["Alice", 30, "Moscow"]
d = dict(zip(keys, values))
print(d)
{'name': 'Alice', 'age': 30, 'city': 'Moscow'}

Инверсия словаря (значения становятся ключами)

Пример
original = {"a": 1, "b": 2, "c": 3}
# При условии уникальности значений
inverted = {v: k for k, v in original.items()}
print(inverted)
# Если значения могут повторяться, использовать списки
original2 = {"a": 1, "b": 2, "c": 1}
from collections import defaultdict
inv_default = defaultdict(list)
for k, v in original2.items():
    inv_default[v].append(k)
print(dict(inv_default))
{1: 'a', 2: 'b', 3: 'c'}
{1: ['a', 'c'], 2: ['b']}

Словарь dict в Python - comments

En
Python dict (python)