Добавление и изменение пар в словаре
Одна операция на всё: d[ключ] = значение добавляет новую пару или заменяет старую. Плюс уникальность ключей, порядок вставки и счётчики, которые пишутся в одну строку.
Редакция Питоники
Словарь из первого урока был собран целиком, одной записью в фигурных скобках. В жизни так бывает редко: товары поступают по одному, оценки появляются по мере учёбы, настройки меняются на ходу. Хорошая новость: для добавления и изменения пар в Python одна и та же операция — присваивание по ключу.
Новая пара: d[ключ] = значение
Записываем ключ в квадратных скобках, справа — значение. Если такого ключа в словаре ещё нет, рождается новая пара. Присваивание по ключу делает обе работы: новой пары нет — она появится, пара есть — значение заменится.
stock = {'молоко': 12}
stock['хлеб'] = 5
stock['сыр'] = 8
print(stock)
{'молоко': 12, 'хлеб': 5, 'сыр': 8}Новые пары встают в конец — и печатаются в том же порядке. Словарь помнит порядок вставки: сначала добавили 'хлеб', потом 'сыр' — в этом порядке они и живут. Так пустой словарь {} из урока про создание превращается в полноценный справочник, пара за парой.
Тот же ключ — другая работа
stock = {'молоко': 12, 'хлеб': 5}
stock['молоко'] = 10
print(stock)
{'молоко': 10, 'хлеб': 5}- ключа ещё нет — пара добавляется в конец словаря;
- ключ уже есть — значение заменяется, позиция пары и остальные пары не трогаются;
- третьего не дано: двух пар с одним ключом в словаре не бывает никогда.
prices = {'молоко': 89, 'молоко': 99}
print(prices)
print(len(prices))
{'молоко': 99}
1Уникальность ключей — не причуда, а фундамент всей адресации словаря: имя ведёт ровно к одному значению, поэтому поиск по ключу однозначен. Типичный рабочий сценарий перезаписи — обновление по свежим данным: цена изменилась, счёт вырос. Новое значение часто считают от старого — читают по ключу и тут же записывают обратно; у прибавления есть и короткая запись +=. Ключ при этом должен существовать, иначе чтение упадёт: как проверить его заранее — в уроке про in.
score = {'Анна': 12}
score['Анна'] = score['Анна'] + 3
print(score)
{'Анна': 15}Замена не двигает пару на новое место
Вот место, где словарь ведёт себя не так, как ожидают. Многие думают, что присваивание по существующему ключу «пересоздаёт» пару, и та встаёт в конец. Нет: пара сохраняет свою позицию, меняется только значение. Проверяется это просто.
cart = {}
cart['чай'] = 1
cart['кофе'] = 2
cart['чай'] = 3
print(cart)
print(list(cart))
{'чай': 3, 'кофе': 2}
['чай', 'кофе']Чай остался первым, хотя его перезаписали последним. Словарь помнит не «последнее действие», а «порядок первого появления ключа». Это отличает словарь от обычного объекта с перезаписью и, кстати, ровно поэтому обновление цены в прайсе не сбрасывает позицию товара в выгрузке.
Счётчик в одну строку
Самый частый сценарий, где словарь применяют в реальном коде, — подсчёт. Слов в тексте, голосов в опросе, покупок в заказе. Ручной вариант выглядит так: взять значение, прибавить единицу, записать обратно. Чтобы не падать на первом же новом слове, старое значение нужно доставать с умолчанием.
words = ['чай', 'кофе', 'чай']
count = {}
for w in words:
count[w] = count.get(w, 0) + 1
print(count)
{'чай': 2, 'кофе': 1}Это рабочий код, но писать его руками каждый раз лень. Ровно для таких мест в стандартной библиотеке есть Counter — словарь, который считает сам: в уроке 11 разбираем его подробно. А defaultdict(int) из урока 12 умеет то же самое ещё короче: счётчик стартует с нуля сам, и строка превращается в count[w] += 1 без всякого .get.
Обратите внимание на +=. Это не отдельная операция словаря, а сокращение Python: score['Анна'] += 3 разворачивается в score['Анна'] = score['Анна'] + 3. И тут скрыта ловушка — прочитать значение приходится раньше, чем записать, а значит, ключ обязан существовать. Для счётчика, где ключ может появиться впервые, += не подходит: он уронит программу с KeyError. Либо get с нулём, либо defaultdict.
score = {'Анна': 12, 'Борис': 9}
score['Анна'] += 3
score['Борис'] += 1
print(score)
{'Анна': 15, 'Борис': 10}Удаление дешёвых позиций
Присваивание умеет и обратное: del d[ключ] убирает пару целиком. Нюанс в том, что нельзя удалять прямо во время обхода словаря — Python ломает обход с RuntimeError. Если нужно вычистить дешёвые позиции, сначала соберите ключи-кандидаты в список и удаляйте после цикла.
prices = {'молоко': 89, 'хлеб': 42}
for name in list(prices.keys()):
if prices[name] < 50:
del prices[name]
print(prices)
{'молоко': 89}Обёртка list(...) — обязательная часть приёма. Она делает копию ключей, по которой цикл идёт уже без оглядки на словарь: удалять из оригинала во время такого обхода можно спокойно. Подробнее про запрет менять словарь во время перебора — в уроке 8.
Что дальше
Добавлять и менять пары вы умеете. Обратная операция — удаление — в уроке 6: там четыре инструмента (del, pop, popitem, clear) и разница между ними, которая на практике важнее, чем кажется. А чтобы не гадать, есть ли ключ вообще, — урок 7 про оператор in.
Шпаргалка: добавить, изменить, удалить
| Что хотим | Запись | Что получится |
|---|---|---|
| Добавить пару | d['хлеб'] = 5 | новая пара в конце словаря |
| Изменить значение | d['хлеб'] = 8 | старое значение заменено, позиция та же |
| Увеличить на 3 | d['хлеб'] += 3 | значение плюс 3, ключ обязан существовать |
| Прибавить к заданному | d['хлеб'] = d.get('хлеб', 0) + 3 | работает и для нового ключа |
| Удалить пару | del d['хлеб'] | пара исчезнет, ничего не вернётся |
| Удалить и забрать | price = d.pop('хлеб') | значение попадёт в переменную |
Самая частая ошибка при работе с парами — не в синтаксисе, а в ожиданиях. Первый сюрприз: перезапись не переносит пару на новое место, второй: += требует существующего ключа, третий: дубликат ключа в данных исчезает без следа. Все три мы разобрали — теперь ясно, где искать, если что-то пойдёт не так.
Сначала предскажи ответ в голове — это главный навык программиста.
cart = {'чай': 1}
cart['кофе'] = 2
cart['чай'] = 3
print(cart)
d = {}
d['a'] = 1
d['a'] = 2
d['b'] = 3
print(len(d))
print(d)
score = {'Борис': 10}
score['Борис'] += 5
print(score)
1. Как добавить в словарь stock новую пару: ключ 'сыр', значение 8?
2. Ключ 'молоко' уже есть в словаре. Что сделает stock['молоко'] = 10?
3. Куда встаёт новая пара при добавлении?
4. Что окажется в словаре после prices = {'молоко': 89, 'молоко': 99}?
5. Что делает запись score['Анна'] += 3?
6. Что произойдёт с парой 'чай', если перезаписать её значение в словаре, где она стояла первой?
7. Почему score['Анна'] += 3 упадёт с KeyError, если ключа 'Анна' в словаре нет?
8. Как посчитать слова в списке, не падая на первом новом слове?
Дан словарь cart = {'чай': 1}. Добавь кофе в количестве 2, затем обнови чай до 3. Выведи словарь.
Как добавить элемент в словарь в Python?
Присваиванием по ключу: stock['сыр'] = 8. Если ключа ещё не было, появится новая пара в конце словаря; если ключ существовал — его значение заменится. Отдельного метода add у словаря нет: присваивание делает обе работы.
Урок 2: создание словаряЧто будет, если добавить ключ, который уже есть?
Значение просто заменится: вторая пара не создастся, потому что ключи в словаре уникальны. Позиция пары и остальные пары при этом не меняются — меняется только значение.
Почему {'молоко': 89, 'молоко': 99} не вызывает ошибку?
Дубликат ключа в литерале разрешён и обрабатывается молча: пары с одинаковыми ключами запрещены, поэтому вторая запись перезаписывает первую — останется {'молоко': 99}. Это удобный механизм, но и ловушка: опечатка-дубликат не выдаст себя сообщением.
Как изменить значение в словаре, оттолкнувшись от старого?
Прочитать и записать в одном выражении: score['Анна'] = score['Анна'] + 3, короче — score['Анна'] += 3. Ключ при этом должен существовать, иначе чтение упадёт с KeyError — сначала проверьте его через get или in.
Урок 7: проверка ключа оператором inСдвигается ли пара в словаре, если перезаписать её значение?
Нет. Словарь помнит порядок первого появления ключа, поэтому перезапись меняет только значение, а позиция пары остаётся прежней. Если порядок важен — например, при выгрузке в CSV, — задавайте его явно через sorted.
Урок 13: сортировка словаряКак посчитать, сколько раз встретился каждый элемент списка?
Циклом с обновлением по ключу: count[w] = count.get(w, 0) + 1. Второй вариант — готовое решение из стандартной библиотеки: Counter(words) из модуля collections. Третий — defaultdict(int), который сам создаёт нулевое значение для нового ключа.
Урок 11: CounterПочему нельзя удалять пары прямо во время цикла по словарю?
Python запрещает менять размер словаря посреди обхода: он прервёт программу с RuntimeError: dictionary changed size during iteration. Спасает обёртка list(prices.keys()) — цикл идёт по копии ключей, и удалять из оригинала во время обхода уже можно.
Урок 8: перебор словаряПонравился урок? Сошлитесь на него
«Присваивание по ключу делает обе работы: новой пары нет — она появится, пара есть — значение заменится.»
Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.
Что дальше
Осталось в разделе: 20 из 20. Прогресс хранится в вашем браузере.
Что читать дальше
Словари · Урок 2
Создание словаря: фигурные скобки и dict()
Три способа создать словарь: литерал в фигурных скобках, dict() из списка пар и пустой словарь под наполнение. Плюс разбор, какие ключи годятся и почему fromkeys с пустым списком — ловушка.
Словари · Урок 4
get: безопасное чтение из словаря
Метод get читает словарь без KeyError: без ключа вернёт None, со вторым аргументом — запасное значение. Сравниваем с квадратными скобками, разбираем арифметику с None и молчание get.
Словари · Урок 6
Удаление: del, pop и popitem
Четыре способа убрать данные из словаря: del молча удаляет пару, pop отдаёт значение, popitem снимает последнюю пару, clear чистит всё. Плюс разбор, почему удалять во время обхода нельзя.
Похожие уроки по темам
Подобраны автоматически по пересечению тем и ключевых слов.
Множества · Урок 3
add и update в Python: добавление элементов в set
Множество собрано — теперь пополняем: add кладёт один элемент, update принимает списки, множества и даже строки. Дубликаты исчезают тихо, без ошибок.
python добавить элемент в множестводубликаты python
Исключения · Урок 11
KeyError в Python: ошибки словарей
Словарь не нашёл ключ — и честно сказал об этим KeyError. Разбираем объект ошибки, читаем из него ключ и выбираем между get, in и честным исключением.
keyerror словарь pythonpython словарь нет ключа
Словари · Урок 7
in: проверка ключа в словаре
Оператор in отвечает на вопрос «есть ли такой ключ»: проверка перед доступом вместо KeyError, not in, грабли с проверкой значений и причина скорости поиска.
python dict inпроверить есть ли ключ в словаре