Создание словаря: фигурные скобки и dict()
Три способа создать словарь: литерал в фигурных скобках, dict() из списка пар и пустой словарь под наполнение. Плюс разбор, какие ключи годятся и почему fromkeys с пустым списком — ловушка.
Редакция Питоники
Первый словарь уже получился: в уроке 1 телефонная книга собиралась фигурными скобками. Это главный способ — но не единственный. Разберём все: литерал в скобках, фабрику dict() и пустой словарь, который наполняется по ходу программы. Заодно выясним, какие значения можно ставить в роль ключа.
Литерал: фигурные скобки
Самый частый путь. Внутри фигурных скобок через запятую перечисляются пары, ключ отделяется от значения двоеточием. Функция len() считает пары — не ключи и не значения по отдельности:
prices = {'молоко': 89, 'хлеб': 42}
print(prices)
print(len(prices))
{'молоко': 89, 'хлеб': 42}
2dict(): из списка пар и из другого словаря
Второй способ — встроенная функция dict(). Ей можно передать список пар (в виде кортежей) — например, собранный циклом или прочитанный из файла. Если же передать готовый словарь, функция сделает его копию. А ещё она принимает пары вида имя=значение — имена при этом превращаются в строковые ключи, так удобно описывать короткие наборы опций:
pairs = [('молоко', 89), ('хлеб', 42), ('сыр', 590)]
prices = dict(pairs)
print(prices)
print(len(prices))
{'молоко': 89, 'хлеб': 42, 'сыр': 590}
3options = dict(theme='dark', lang='ru')
backup = dict({'молоко': 89, 'хлеб': 42})
print(options)
print(backup)
{'theme': 'dark', 'lang': 'ru'}
{'молоко': 89, 'хлеб': 42}Какие ключи годятся: строки и числа
Оговорка: имена при записи имя=значение подчиняются правилам имён переменных — латиница, без кавычек, поэтому русский ключ 'молоко' так не передать; для таких ключей остаётся литерал. Ключом же может быть любое неизменяемое значение: строка — самый частый выбор, число — второй (номера месяцев, коды ошибок, id записей). Строки и числа спокойно живут в одном словаре, а доступны каждый по-своему: строка — в кавычках, число — без. Как потом пополнять готовый словарь — урок 5.
calendar = {'год': 2026, 1: 'январь', 12: 'декабрь'}
print(calendar['год'])
print(calendar[1])
print(calendar[12])
2026 январь декабрь
Словарь из двух списков: zip
Отдельно стоит разобрать случай, который встречается на каждом втором собеседовании. Данные приходят двумя списками: один с названиями товаров, второй с ценами. dict() два списка не принимает — ждёт пары. Собирать их руками в цикле — работа, которая ломается при любой опечатке. Помогает встроенная функция zip: она берёт элементы списков попарно и отдаёт пары, а dict() превращает пары в словарь.
names = ['молоко', 'хлеб', 'сыр']
prices = [89, 42, 590]
catalog = dict(zip(names, prices))
print(catalog)
print(catalog['сыр'])
{'молоко': 89, 'хлеб': 42, 'сыр': 590}
590Одна строка вместо цикла с присваиванием. Но есть подвох: zip останавливается на самом коротком списке. Если в названиях пять позиций, а в ценах четыре — пятая молча пропадёт, и словарь получится на пару короче, чем ожидала программа. Данные такой формы лучше проверять: сравните len(names) и len(prices) до сборки.
Пустой словарь и наполнение в цикле
Третий способ — создать пустой словарь и наполнять его по ходу. Это не экзотика: так работает почти любой код, который читает данные построчно. Сначала catalog = {}, потом в цикле catalog[name] = price. Преимущество в том, что не нужно знать заранее, сколько строк придёт, — словарь вырастет ровно настолько, насколько наполнят.
catalog = {}
rows = [('молоко', 89), ('хлеб', 42), ('сыр', 590)]
for name, price in rows:
catalog[name] = price
print(catalog)
print(len(catalog))
{'молоко': 89, 'хлеб': 42, 'сыр': 590}
3Здесь же живёт и первый настоящий сценарий ошибки: если два товара придут с одинаковым названием, второй молча перезапишет первый, и в каталоге окажется товаров меньше, чем строк в исходных данных. Мы на этом уже останавливались в уроке про добавление пар, но при чтении из внешнего источника забыть про это особенно легко.
base = dict.fromkeys(['молоко', 'хлеб', 'сыр'], [])
base['молоко'].append(89)
base['хлеб'].append(42)
print(base)
{'молоко': [89, 42], 'хлеб': [89, 42], 'сыр': [89, 42]}Один и тот же список под тремя ключами — вот что здесь получилось. Для неизменяемых значений, вроде нуля или пустой строки, fromkeys работает нормально: счётчик стартует с нуля у каждого ключа. Проблема ровно в изменяемых значениях.
dict(имя=значение) и когда он удобен
Третий вид вызова dict() принимает пары в виде именованных аргументов: dict(theme='dark', lang='ru'). Имена превращаются в строковые ключи. Ограничение видно сразу: имя аргумента обязано быть корректным идентификатором Python — латиница, без пробелов, без кириллицы. Русский ключ 'молоко' так не передать, для таких случаев остаётся литерал.
options = dict(theme='dark', lang='ru', retries=3)
print(options)
print(len(options))
{'theme': 'dark', 'lang': 'ru', 'retries': 3}
3Зато читается такой код отлично — особенно когда это набор параметров по умолчанию: сразу видно, какие опции есть и какие у них значения. В реальных проектах такой словарь потом расширяют: options['timeout'] = 30. Поменять значение по ключу — одна строка, и все места, где опция читалась, сразу увидят новое.
Копия или оригинал
Отдельного внимания заслуживает dict(существующий_словарь). Это не «тот же самый» словарь, а независимая копия: изменение оригинала не тронет копию, и наоборот. Проверить это просто — и заодно полезно знать, потому что расхождение копий потом ищут часами.
original = {'theme': 'dark', 'lang': 'ru'}
copy = dict(original)
copy['theme'] = 'light'
print(original)
print(copy)
print(original is copy)
{'theme': 'dark', 'lang': 'ru'}
{'theme': 'light', 'lang': 'ru'}
FalseОригинал остался тёмным, копия — светлой, и is честно отвечает False: это два разных объекта. Правда, копия копирует только верхний уровень — вложенные словари и списки останутся общими. Про это — в уроке 19, там разбирают глубокие копии.
Словарь или список кортежей
Пара «ключ: значение» внутри списка — почти то же самое, только медленнее. Поиск по списку идёт перебором: чтобы найти цену молока в каталоге из 30 000 позиций, программа в среднем сравнит 15 000 кортежей. Словарь ищет иначе — он считает хеш ключа и сразу прыгает в нужную ячейку, поэтому ответ приходит независимо от размера каталога. На сотнях записей разницу не почувствуешь, она всплывает там, где записей тысячи.
Отсюда простое правило: к данным обращаются по имени — берите словарь, по позиции — список. Смешанный вариант разваливается хуже всего: список кортежей, где имя лежит в первом элементе, обращается к себе перебором, и при тысяче запросов в секунду это уже видно по отклику страницы. Переезд такого списка в словарь занимает полчаса, а эффект виден сразу.
rows = [('молоко', 89), ('хлеб', 42), ('сыр', 590)]
prices = dict(rows)
def find_price(rows, key):
for name, price in rows:
if name == key:
return price
return None
print(find_price(rows, 'сыр'))
print(prices['сыр'])
590 590
Что дальше
Словарь теперь можно создать тремя способами — литералом, через dict() и пустым с наполнением в цикле. Дальше самое интересное: что произойдёт, когда вы обратитесь к ключу, которого в словаре нет. В уроке 3 — настоящий traceback с KeyError и разбор того, как его читать, а в уроке 4 — мягкая замена через get.
Сначала предскажи ответ в голове — это главный навык программиста.
empty = {}
print(empty)
print(len(empty))
pairs = [('a', 1), ('b', 2)]
d = dict(pairs)
print(d)
d = {1: 'январь', '1': 'one'}
print(d[1])
print(d['1'])
1. Как создать пустой словарь?
2. Что создаст запись {'а', 'б'} — с запятой, но без двоеточий?
3. Что вернёт len() для словаря из трёх пар?
4. Что сделает dict([('чай', 30), ('кофе', 120)])?
5. Какой ключ недопустим в словаре?
6. Как из двух списков names и prices собрать один словарь?
7. Что произойдёт, если длины names и prices различаются?
8. Почему dict.fromkeys(['a', 'b'], []) — ловушка?
Дан список пар pairs = [('фильм', 8), ('сериал', 9)]. Преврати его в словарь ratings через dict() и выведи словарь, затем выведи, сколько в нём пар.
Как создать словарь в Python?
Чаще всего литералом в фигурных скобках: prices = {'молоко': 89, 'хлеб': 42}. Пустой словарь — просто {}. Альтернатива — функция dict(): ей можно передать список пар dict([('чай', 30)]) или другой словарь, чтобы получить копию.
Урок 1: первый словарьЧем {} отличается от dict()?
Результат одинаковый — пустой словарь. Но {} — это синтаксис литерала, а dict() — функция, которая к тому же умеет строить словарь из списка пар или копировать готовый словарь. В коде для пустого словаря обычно пишут {} — короче.
Можно ли сделать словарь из двух списков?
Напрямую dict() два списка не принимает: сначала собери из них список пар — zip(имена, значения) вернёт именно его, и dict(zip(names, prices)) соберёт словарь. А список пар (кортежей) dict() превращает в словарь напрямую, как показано в уроке.
Почему список нельзя сделать ключом словаря?
Ключ обязан быть неизменяемым: словарь находит значение по ключу мгновенно и не должен бояться, что ключ однажды поменяется. Строки и числа не меняются — они подходят; список можно изменить — поэтому Python запрещает его в роли ключа.
Как собрать словарь из двух списков одинаковой длины?
Через zip: dict(zip(names, prices)). zip берёт элементы списков попарно, а dict превращает пары в словарь. Важно помнить, что zip останавливается на самом коротком списке — если длины разошлись, лишние значения молча пропадут, без ошибки.
Урок 2: создание словаряЧто делает dict.fromkeys(['a', 'b'], [])?
Создаёт словарь, где у ключей 'a' и 'b' одно и то же значение — один и тот же объект списка. Изменение одного списка будет видно и в другом, потому что это не две копии, а одна. Для списков под каждым ключом нужен defaultdict(list).
Урок 12: defaultdictdict(уже_существующий_словарь) — это копия?
Да, независимая копия верхнего уровня: изменения оригинала не видны в копии и наоборот. Но вложенные словари и списки копируются как ссылки — они останутся общими. Для глубокого копирования есть отдельный приём, разобранный в уроке 19.
Урок 19: сравнение словарей и копированиеПонравился урок? Сошлитесь на него
«Внутри фигурных скобок через запятую перечисляются пары, ключ отделяется от значения двоеточием.»
Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.
Что дальше
Осталось в разделе: 20 из 20. Прогресс хранится в вашем браузере.
Что читать дальше
Словари · Урок 1
Словарь в Python: ключ и значение
Словарь — структура «ключ — значение»: достаём номер телефона по имени из телефонной книги, сравниваем dict со списком на живых данных и заглядываем под капот — как Python находит значение по ключу.
Словари · Урок 5
Добавление и изменение пар в словаре
Одна операция на всё: d[ключ] = значение добавляет новую пару или заменяет старую. Плюс уникальность ключей, порядок вставки и счётчики, которые пишутся в одну строку.
Словари · Урок 7
in: проверка ключа в словаре
Оператор in отвечает на вопрос «есть ли такой ключ»: проверка перед доступом вместо KeyError, not in, грабли с проверкой значений и причина скорости поиска.
Похожие уроки по темам
Подобраны автоматически по пересечению тем и ключевых слов.
json · Урок 8
Путь к значению: достаём данные из глубины
Цепочки data["user"]["name"] и data["items"][0]["price"], KeyError у отсутствующих полей и get с умолчанием — спуск по типичному ответу API без падений.
dict get python умолчаниеpython get вложенный словарь
Множества · Урок 2
Создание множеств: {} и set() — литерал, список, строка
Два способа создать множество: литерал в фигурных скобках и set() от списка или строки. Пустые скобки — это словарь, поэтому пустое множество пишут set().
создание множества pythonset от списка
Словари · Урок 15
dict comprehension: словарь за строку
Dict comprehension собирает словарь за одну строку: квадраты чисел, цены со скидкой, фильтр по условию, инверсия ключей и значений — и словарь из списка через enumerate.
dict comprehension pythonгенератор словаря python