Django-Admin.ru

Словари в Python (dict): методы и примеры

Словарь в Python (dict): создание, доступ по ключу, get и setdefault, обход items, объединение, сортировка по значению, список словарей и ошибка KeyError.

Редакция Django-Admin.ru
· обновлено · 10 мин чтения

Содержание · 15 разделов
  1. Как создать словарь
  2. Как получить значение по ключу: [] и get
  3. Проверка ключа: оператор in
  4. Добавление, изменение и удаление элементов
  5. setdefault: прочитать или создать
  6. Основные методы словаря Python
  7. Обход словаря: keys, values, items
  8. Генератор словарей (dict comprehension)
  9. Объединение словарей: | и update
  10. Сортировка словаря по ключу и по значению
  11. Порядок ключей
  12. Вложенные словари
  13. Список словарей и его сортировка
  14. defaultdict и Counter
  15. Частые ошибки
  16. KeyError при обращении к несуществующему ключу
  17. Изменение словаря во время обхода
  18. Список в качестве ключа
  19. Копия, которая не копия
  20. Частые вопросы
  21. Как найти ключ по значению?
  22. Как проверить, что словарь пустой?
  23. Как сохранить словарь в JSON и прочитать обратно?
  24. Как переименовать ключ?
  25. Как получить первый ключ словаря?
  26. Итог

Словарь в Python (dict) хранит пары «ключ — значение» и находит значение по ключу за постоянное в среднем время, независимо от размера словаря. Короткий ответ: словарь создаётся фигурными скобками {"name": "Анна", "age": 30}, значение читается как d["name"], а безопасно, без ошибки при отсутствии ключа, — через d.get("name").

Ниже — все основные операции со словарём: создание, методы словаря Python, обход, объединение, сортировка, вложенные словари и список словарей. Все примеры проверены на Python 3.12; вывод показан комментарием # →.

Как создать словарь

user = {"name": "Анна", "age": 30}       # литерал
empty = {}                               # пустой словарь (не множество!)
point = dict(x=1, y=2)                   # через именованные аргументы
pairs = dict([("a", 1), ("b", 2)])       # из списка пар
keys = ["id", "title"]
values = [7, "Python"]
book = dict(zip(keys, values))           # из двух списков

print(point)  # → {'x': 1, 'y': 2}
print(pairs)  # → {'a': 1, 'b': 2}
print(book)   # → {'id': 7, 'title': 'Python'}
print(dict.fromkeys(["a", "b"], 0))  # → {'a': 0, 'b': 0}

Ключом может быть только хешируемый объект: строка, число, кортеж из хешируемых элементов, None. Список или другой словарь ключом быть не может. Значения — любые объекты, в том числе списки и словари.

Как получить значение по ключу: [] и get

Значение по ключу читают квадратными скобками. Если ключа нет, Python выбросит KeyError:

user = {"name": "Анна", "age": 30}
print(user["name"])  # → Анна
user["email"]  # → KeyError: 'email'

Метод get() возвращает None (или значение по умолчанию), если ключа нет, и не падает:

user = {"name": "Анна", "age": 30}
print(user.get("email"))               # → None
print(user.get("email", "не указан"))  # → не указан
print(user.get("age", 0))              # → 30

Используйте d[key], когда ключ обязан быть в словаре и его отсутствие — ошибка. Используйте get(), когда ключ необязателен.

Проверка ключа: оператор in

user = {"name": "Анна", "age": 30}
print("name" in user)      # → True
print("email" not in user)  # → True
print("Анна" in user)      # → False

in проверяет только ключи. Чтобы найти значение, проверяйте "Анна" in user.values() — но это уже линейный поиск по всем значениям.

Добавление, изменение и удаление элементов

Присваивание по ключу добавляет новый элемент словаря или перезаписывает существующий:

user = {"name": "Анна"}
user["age"] = 30         # добавили
user["name"] = "Мария"   # изменили
print(user)  # → {'name': 'Мария', 'age': 30}

Для удаления есть несколько способов:

user = {"name": "Анна", "age": 30, "city": "Казань", "role": "admin"}

del user["role"]               # удалить ключ (KeyError, если его нет)
age = user.pop("age")          # удалить и вернуть значение
phone = user.pop("phone", None)  # без ошибки, если ключа нет
last = user.popitem()          # удалить последнюю добавленную пару

print(age, phone)  # → 30 None
print(last)        # → ('city', 'Казань')
print(user)        # → {'name': 'Анна'}
user.clear()
print(user)        # → {}

setdefault: прочитать или создать

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

words = ["яблоко", "арбуз", "ягода", "апельсин"]
groups = {}
for word in words:
    groups.setdefault(word[0], []).append(word)
print(groups)  # → {'я': ['яблоко', 'ягода'], 'а': ['арбуз', 'апельсин']}

Основные методы словаря Python

Метод / операцияЧто делает
d[key]значение по ключу, KeyError если ключа нет
d.get(key, default)значение или default (по умолчанию None)
d.setdefault(key, val)значение; если ключа нет — записывает val и возвращает его
d.keys()представление ключей
d.values()представление значений
d.items()представление пар (ключ, значение)
d.update(other)добавляет/перезаписывает пары из другого словаря
d.pop(key, default)удаляет ключ и возвращает значение
d.popitem()удаляет и возвращает последнюю добавленную пару
d.copy()поверхностная копия
d.clear()очищает словарь
dict.fromkeys(keys, v)новый словарь с ключами из keys и значением v
len(d), key in dколичество пар, проверка ключа

Полный список — в документации по типу dict.

Обход словаря: keys, values, items

Цикл for по словарю перебирает ключи. Чтобы получить и ключ, и значение, используйте items():

prices = {"кофе": 250, "чай": 180, "сок": 220}

for name in prices:              # перебор ключей
    print(name)
for name, price in prices.items():  # пары ключ — значение
    print(f"{name}: {price} ₽")
print(sum(prices.values()))      # только значения
кофе
чай
сок
кофе: 250 ₽
чай: 180 ₽
сок: 220 ₽
650

Методы keys(), values() и items() возвращают не списки, а представления (views): они отражают текущее состояние словаря. Если нужен настоящий список, оберните в list(): list(prices) вернёт список ключей. Если в цикле нужен ещё и порядковый номер, пригодится enumerate: for i, (name, price) in enumerate(prices.items(), 1).

Генератор словарей (dict comprehension)

Словарь можно собрать одной строкой по шаблону {ключ: значение for ... in ...}:

squares = {n: n ** 2 for n in range(1, 6)}
print(squares)  # → {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

prices = {"кофе": 250, "чай": 180, "сок": 220}
cheap = {k: v for k, v in prices.items() if v < 230}
print(cheap)  # → {'чай': 180, 'сок': 220}

swapped = {v: k for k, v in prices.items()}  # поменять ключи и значения
print(swapped)  # → {250: 'кофе', 180: 'чай', 220: 'сок'}

Объединение словарей: | и update

С Python 3.9 словари объединяются оператором |, при совпадении ключей побеждает правый словарь. update() и |= изменяют словарь на месте:

defaults = {"theme": "light", "lang": "ru"}
custom = {"theme": "dark"}

settings = defaults | custom
print(settings)  # → {'theme': 'dark', 'lang': 'ru'}

defaults.update(custom)        # то же самое, но меняет defaults
print(defaults)  # → {'theme': 'dark', 'lang': 'ru'}

merged = {**defaults, "debug": True}  # распаковка — работает и в старых версиях
print(merged)  # → {'theme': 'dark', 'lang': 'ru', 'debug': True}

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

Функция sorted() возвращает список; чтобы снова получить словарь, оберните результат в dict():

scores = {"Олег": 72, "Анна": 95, "Иван": 88}

by_key = dict(sorted(scores.items()))
print(by_key)  # → {'Анна': 95, 'Иван': 88, 'Олег': 72}

by_value = dict(sorted(scores.items(), key=lambda item: item[1], reverse=True))
print(by_value)  # → {'Анна': 95, 'Иван': 88, 'Олег': 72}

print(max(scores, key=scores.get))  # → Анна

max(scores, key=scores.get) возвращает ключ с наибольшим значением — частая задача «найти лучшего».

Порядок ключей

С Python 3.7 словарь гарантированно сохраняет порядок вставки: ключи перебираются в том порядке, в каком были добавлены. Перезапись значения существующего ключа порядок не меняет, а удаление и повторное добавление переносит ключ в конец.

Вложенные словари

Значением может быть другой словарь — так описывают структуры вроде JSON:

config = {
    "db": {"host": "localhost", "port": 5432},
    "debug": True,
}
print(config["db"]["port"])  # → 5432
config["db"]["port"] = 6432
print(config.get("cache", {}).get("ttl", 60))  # → 60

Цепочка get(..., {}) позволяет безопасно читать необязательные вложенные ключи.

Список словарей и его сортировка

Список словарей — типичный формат данных из API, CSV или базы. Его сортируют через sorted() с ключом:

users = [
    {"name": "Олег", "age": 25},
    {"name": "Анна", "age": 31},
    {"name": "Иван", "age": 19},
]

by_age = sorted(users, key=lambda u: u["age"])
print([u["name"] for u in by_age])  # → ['Иван', 'Олег', 'Анна']

adults = [u for u in users if u["age"] >= 21]
print(len(adults))  # → 2

ages = {u["name"]: u["age"] for u in users}
print(ages)  # → {'Олег': 25, 'Анна': 31, 'Иван': 19}

Вместо lambda можно использовать operator.itemgetter("age") — результат тот же. Подробнее о работе со списками — в статье о списках в Python.

defaultdict и Counter

В модуле collections есть два полезных наследника dict:

from collections import Counter, defaultdict

groups = defaultdict(list)          # отсутствующий ключ получает []
for word in ["яблоко", "арбуз", "ягода"]:
    groups[word[0]].append(word)
print(dict(groups))  # → {'я': ['яблоко', 'ягода'], 'а': ['арбуз']}

text = "мама мыла раму мама"
counts = Counter(text.split())
print(counts)  # → Counter({'мама': 2, 'мыла': 1, 'раму': 1})
print(counts.most_common(1))  # → [('мама', 2)]

defaultdict избавляет от проверок «есть ли ключ», а Counter считает частоты элементов.

Частые ошибки

KeyError при обращении к несуществующему ключу

Самая частая ошибка со словарями. Проверьте ключ через in, используйте get() или перехватите исключение — подробнее о try/except в статье об обработке исключений:

user = {"name": "Анна"}
try:
    print(user["age"])
except KeyError as e:
    print("Нет ключа:", e)  # → Нет ключа: 'age'

Частая причина — регистр или пробел в ключе: "Name" и "name" — разные ключи.

Изменение словаря во время обхода

stock = {"кофе": 0, "чай": 5}
for name in stock:
    if stock[name] == 0:
        del stock[name]  # → RuntimeError: dictionary changed size during iteration

Обходите копию ключей — for name in list(stock): — или соберите новый словарь генератором: {k: v for k, v in stock.items() if v}.

Список в качестве ключа

d = {}
d[[1, 2]] = "точка"  # → TypeError: unhashable type: 'list'

Используйте кортеж: d[(1, 2)] = "точка".

Копия, которая не копия

b = a не копирует словарь — обе переменные ссылаются на один объект. a.copy() создаёт новый словарь, но вложенные объекты остаются общими. Для полной копии используйте copy.deepcopy(a).

Частые вопросы

Как найти ключ по значению?

Прямого метода нет: словарь ищет только по ключам. Переберите пары и отберите нужные:

scores = {"Олег": 72, "Анна": 95, "Иван": 72}
print([k for k, v in scores.items() if v == 72])  # → ['Олег', 'Иван']
print(next((k for k, v in scores.items() if v == 95), None))  # → Анна

Если такой поиск нужен часто, постройте обратный словарь {v: k for k, v in d.items()} один раз.

Как проверить, что словарь пустой?

Пустой словарь в условии ложен, поэтому достаточно if not d:. Сравнивать len(d) == 0 тоже можно, но это длиннее.

Как сохранить словарь в JSON и прочитать обратно?

import json

data = {"name": "Анна", "tags": ["admin", "staff"]}
text = json.dumps(data, ensure_ascii=False)
print(text)  # → {"name": "Анна", "tags": ["admin", "staff"]}
print(json.loads(text) == data)  # → True

ensure_ascii=False оставляет кириллицу читаемой вместо последовательностей вида \u0410.

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

Отдельного метода нет: заберите значение через pop() и запишите его под новым ключом. Переименованный ключ окажется в конце словаря.

user = {"login": "anna", "age": 30}
user["name"] = user.pop("login")
print(user)  # → {'age': 30, 'name': 'anna'}

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

Индексов у словаря нет, поэтому первый ключ берут из итератора: next(iter(d)). Для пустого словаря передайте значение по умолчанию, иначе будет StopIteration.

prices = {"кофе": 250, "чай": 180}
print(next(iter(prices)))          # → кофе
print(next(iter(prices.items())))  # → ('кофе', 250)
print(next(iter({}), None))        # → None

Итог

Словарь — основная структура для данных «по ключу»: читайте значения через d[key] или get(), обходите пары через items(), объединяйте через |, а для подсчёта и группировки берите Counter и defaultdict. Остальные конструкции языка собраны в шпаргалке по синтаксису Python, а строки в словарь и обратно удобно превращать методами split и join.

  • #Python
  • #dict
  • #Словари
  • #Синтаксис
  • #Коллекции
↑ ↓ выборEnter открытьEsc закрыть