Словари в Python (dict): методы и примеры
Словарь в Python (dict): создание, доступ по ключу, get и setdefault, обход items, объединение, сортировка по значению, список словарей и ошибка KeyError.
Содержание · 15 разделов
- Как создать словарь
- Как получить значение по ключу: [] и get
- Проверка ключа: оператор in
- Добавление, изменение и удаление элементов
- setdefault: прочитать или создать
- Основные методы словаря Python
- Обход словаря: keys, values, items
- Генератор словарей (dict comprehension)
- Объединение словарей: | и update
- Сортировка словаря по ключу и по значению
- Порядок ключей
- Вложенные словари
- Список словарей и его сортировка
- defaultdict и Counter
- Частые ошибки
- KeyError при обращении к несуществующему ключу
- Изменение словаря во время обхода
- Список в качестве ключа
- Копия, которая не копия
- Частые вопросы
- Как найти ключ по значению?
- Как проверить, что словарь пустой?
- Как сохранить словарь в JSON и прочитать обратно?
- Как переименовать ключ?
- Как получить первый ключ словаря?
- Итог
Словарь в 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
- #Словари
- #Синтаксис
- #Коллекции