Словари (dict) в Python: шпаргалка

Зачем аналитику dict

Словарь — самая используемая структура данных после списка. Подсчёт частот, группировка, кеширование, параметры — везде нужен dict.

Создание

# Литерал
d = {'name': 'Иван', 'age': 25}

# Конструктор
d = dict(name='Иван', age=25)

# Из списка пар
d = dict([('a', 1), ('b', 2)])

# Из двух списков через zip
d = dict(zip(['a', 'b'], [1, 2]))

# Пустой
d = {}

Доступ и изменение

d = {'name': 'Иван', 'age': 25}

# Получить значение
d['name']          # 'Иван'
d['city']          # KeyError!

# Безопасно: get
d.get('city')                  # None
d.get('city', 'Москва')        # 'Москва' (default)

# Изменить
d['age'] = 26

# Удалить
del d['age']
d.pop('age')       # вернёт значение, удалит ключ
d.pop('x', None)   # без ошибки, если нет

# Очистить
d.clear()

Проверки

'name' in d          # True/False
'city' not in d      # True/False
len(d)               # количество пар

Итерация

# По ключам (по умолчанию)
for key in d:
    print(key)

# По ключам явно
for key in d.keys():
    print(key)

# По значениям
for val in d.values():
    print(val)

# По парам
for key, val in d.items():
    print(key, val)

Если хочется сразу закрепить тему на практике — открой тренажёр в Telegram. 10 минут в день — и синтаксис в пальцах.

Слияние и обновление

d1 = {'a': 1, 'b': 2}
d2 = {'b': 3, 'c': 4}

# Метод update
d1.update(d2)
# d1 = {'a': 1, 'b': 3, 'c': 4} — d2 победил

# Python 3.9+ — оператор |
d = d1 | d2

# Создать копию
d_copy = d1.copy()
d_copy = dict(d1)

Dict comprehension

squares = {x: x**2 for x in range(5)}
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

# Фильтр
adults = {name: age for name, age in d.items() if age >= 18}

# Инвертировать
inv = {v: k for k, v in d.items()}

collections.Counter

Подсчёт частот — одна из самых частых задач:

from collections import Counter

# Из списка
c = Counter(['a', 'b', 'a', 'c', 'b', 'a'])
# Counter({'a': 3, 'b': 2, 'c': 1})

# Из строки
c = Counter('hello')
# Counter({'l': 2, 'h': 1, 'e': 1, 'o': 1})

# Топ-N
c.most_common(2)
# [('a', 3), ('b', 2)]

# Математика со счётчиками
c1 + c2    # сложение частот
c1 - c2    # вычитание

collections.defaultdict

Dict с значением по умолчанию:

from collections import defaultdict

# Группировка
groups = defaultdict(list)
for name, age in [('Иван', 25), ('Петр', 25), ('Аня', 30)]:
    groups[age].append(name)
# {25: ['Иван', 'Петр'], 30: ['Аня']}

# Счётчик
counts = defaultdict(int)
for x in data:
    counts[x] += 1

Без defaultdict нужно проверять наличие ключа каждый раз.

Сортировка

# По ключам
sorted(d.items())

# По значениям
sorted(d.items(), key=lambda x: x[1])

# Убывание
sorted(d.items(), key=lambda x: x[1], reverse=True)

# В dict (Python 3.7+ сохраняет порядок)
dict(sorted(d.items(), key=lambda x: x[1]))

Частые приёмы

1. Подсчёт частот

from collections import Counter
c = Counter(words)
c.most_common(5)

2. Группировка

from collections import defaultdict
groups = defaultdict(list)
for item in items:
    groups[item.category].append(item)

3. Безопасное обновление значения

# Плохо — если нет ключа, KeyError
d[key] += 1

# Хорошо
d[key] = d.get(key, 0) + 1

# Лучше — defaultdict
d = defaultdict(int)
d[key] += 1

4. Inverse (обратный dict)

inv = {v: k for k, v in d.items()}

Осторожно: если значения не уникальны, некоторые пары потеряются.

5. Кэширование (memoization)

cache = {}
def expensive_func(x):
    if x not in cache:
        cache[x] = heavy_calculation(x)
    return cache[x]

Чтобы не только читать теорию, но и решать реальные задачи — загляните в бот Карьерника. Там по каждой теме подборка вопросов с разборами.

Dict vs list

Когда что использовать:

Задача Структура
Упорядоченная коллекция list
Поиск по ключу O(1) dict
Подсчёт элементов Counter (dict)
Группировка defaultdict(list)
Удаление дубликатов + порядок не важен set
Хранение конфигурации/параметров dict

Производительность

  • Доступ по ключу: O(1) средне.
  • Вставка/удаление: O(1) средне.
  • Обход: O(n).
  • in: O(1) — намного быстрее, чем поиск в list (O(n)).

На больших данных if x in dict в 100x быстрее if x in list.

10 задач с собесов

1. Подсчёт слов в тексте

from collections import Counter
text = 'hello world hello python'
Counter(text.split())

2. Найти самое частое значение

Counter(data).most_common(1)[0]

3. Группировка по категории

from collections import defaultdict
groups = defaultdict(list)
for item in items:
    groups[item.category].append(item)

4. Инверт словаря

{v: k for k, v in d.items()}

5. Словарь в DataFrame

import pandas as pd
pd.DataFrame(list(d.items()), columns=['key', 'value'])

6. Топ-N ключей по значениям

sorted(d.items(), key=lambda x: x[1], reverse=True)[:N]

7. Слияние двух словарей

d = d1 | d2  # Python 3.9+
d = {**d1, **d2}  # любой версии

8. Проверка, есть ли все ключи

required = ['name', 'age', 'email']
if all(k in d for k in required):
    ...

9. Удалить ключи с None-значениями

{k: v for k, v in d.items() if v is not None}

10. JSON → dict

import json
d = json.loads('{"a": 1}')

Как тренироваться

Dict — базовая структура. Учитесь её использовать везде, где напрашивается: подсчёт, группировка, кеш, параметры.

Совет: на собесе, когда задача на «подсчёт чего-то» или «группировку» — сразу думайте про Counter или defaultdict. Чистый код + быстрое решение.

Читайте также

FAQ

dict или OrderedDict?

С Python 3.7 обычный dict сохраняет порядок вставки. OrderedDict нужен только если используете move_to_end или подобные методы.

dict или namedtuple?

Dict — если ключи меняются. Namedtuple — если фиксированная структура (x, y координаты, Point).

Когда Counter, когда defaultdict(int)?

Counter — специально для подсчёта. Имеет most_common, арифметику. defaultdict(int) — проще, когда нужен только счётчик без доп. функций.

Dict hashable?

Ключи должны быть hashable (неизменяемые): int, str, tuple. Список или dict в ключе — ошибка.