Словари в Python
Допустим, вы храните оценки студентов. Первая мысль — два списка: имена и оценки, и одинаковая позиция связывает их.
Python 3.13names = ["John", "Mary", "Kate"] grades = [90, 75, 80]
Чтобы узнать оценку Мэри, сначала нужно найти, на какой позиции она стоит в names, а потом прочитать ту же позицию в grades. Добавляете студента — нельзя забыть дописать значение во второй список. Стоит одному списку сбиться на один элемент, и Мэри получает чужую оценку, а программа об этом даже не сообщит. Связь между именем и оценкой держится только в вашей голове, а не в коде.
Словарь убирает посредника-индекс и связывает имя со значением напрямую.
Python 3.13grades = {"John": 90, "Mary": 75, "Kate": 80} print(grades["Mary"])75
Словарь (dict) — это коллекция пар «ключ — значение». Вы обращаетесь к значению по ключу, а не по числовой позиции.
Телефонная книга устроена так же: вы ищете человека по имени, а не по номеру строки.
Как создать словарь
Чаще всего словарь записывают прямо, в фигурных скобках: пара ключ: значение, пары через запятую.
Python 3.13# Пустой словарь, который заполним позже prices = {} # Словарь сразу с данными person = {"name": "John", "age": 30, "city": "New York"} print(person){'name': 'John', 'age': 30, 'city': 'New York'}
Если пары уже лежат где-то готовыми, например приходят парами, словарь можно собрать функцией dict().
Python 3.13pairs = [("name", "Anna"), ("age", 28), ("city", "Berlin")] person = dict(pairs) print(person){'name': 'Anna', 'age': 28, 'city': 'Berlin'}
Чтение значения: скобки против get
Самый прямой способ получить значение — квадратные скобки с ключом.
Python 3.13person = {"name": "John", "age": 30} print(person["name"])John
Но если ключа в словаре нет, скобки не возвращают пустоту, а останавливают программу с ошибкой KeyError.
Python 3.13person = {"name": "John", "age": 30} print(person["phone"]) # KeyError: 'phone' — такого ключа в словаре нет
Это не недостаток, а защита: чаще всего обращение к несуществующему ключу — это опечатка или сломанная логика, и лучше узнать о ней сразу. Скобки уместны, когда вы уверены, что ключ есть.
Когда ключа может и не быть, есть метод get(). Он вернёт None вместо ошибки, а если передать второй аргумент — то его как значение по умолчанию.
Python 3.13person = {"name": "John", "age": 30} print(person.get("phone"))Noneprint(person.get("phone", "не указан"))не указан
Отсюда простое правило выбора: скобки — когда отсутствие ключа это ошибка, get() — когда отсутствие это нормальный случай, который вы готовы обработать.
Добавление и изменение
У словаря один и тот же синтаксис и добавляет ключ, и меняет существующий: присваивание по ключу. Если ключа не было — он появится, если был — значение перезапишется.
Python 3.13person = {"name": "John", "age": 30} # Ключа "city" не было — он добавляется person["city"] = "New York" print(person){'name': 'John', 'age': 30, 'city': 'New York'}# Ключ "age" уже есть — значение заменяется person["age"] = 31 print(person){'name': 'John', 'age': 31, 'city': 'New York'}
Когда нужно внести сразу несколько изменений, удобнее update(): он добавляет новые ключи и перезаписывает совпавшие за один вызов.
Python 3.13person = {"name": "John", "age": 31} person.update({"age": 32, "job": "developer"}) print(person){'name': 'John', 'age': 32, 'job': 'developer'}
Проверка наличия ключа
Чтобы заранее узнать, есть ли ключ, используют оператор in. Это и есть способ не нарваться на KeyError, когда скобки всё-таки нужны.
Python 3.13person = {"name": "John", "age": 30} print("name" in person)Trueprint("phone" in person)False
Удаление
Убрать ключ можно оператором del. Но если ключа нет, del тоже падает с KeyError.
Python 3.13person = {"name": "John", "age": 30, "job": "developer"} del person["job"] print(person){'name': 'John', 'age': 30}
Метод pop() удаляет ключ и заодно возвращает его значение — пригодится, когда удаляемое значение ещё нужно. Со вторым аргументом он не падает на отсутствующем ключе, а возвращает значение по умолчанию.
Python 3.13person = {"name": "John", "age": 30} age = person.pop("age") print(age)30# Ключа "phone" нет, но второй аргумент спасает от ошибки phone = person.pop("phone", "не указан") print(phone)не указан
Перебор словаря
По словарю можно пройтись циклом. По умолчанию цикл for идёт по ключам, а значение легко достать по ключу.
Python 3.13grades = {"John": 90, "Mary": 75, "Kate": 80} for name in grades: print(name, ":", grades[name])John : 90 Mary : 75 Kate : 80
Если внутри цикла нужны и ключ, и значение, метод items() отдаёт их парой сразу, без обращения по ключу.
Python 3.13grades = {"John": 90, "Mary": 75, "Kate": 80} for name, grade in grades.items(): print(name, ":", grade)John : 90 Mary : 75 Kate : 80
Есть и парные методы: keys() отдаёт только ключи, values() — только значения. Они нужны, когда вторая половина пары в цикле не используется.
Python 3.13grades = {"John": 90, "Mary": 75, "Kate": 80} total = 0 for grade in grades.values(): total = total + grade print("Сумма баллов:", total)Сумма баллов: 245
Частая задача: подсчёт
Словарь хорошо подходит, чтобы что-то посчитать: ключ — это объект, значение — счётчик. Посчитаем, сколько раз встречается каждое слово.
В лоб это выглядит так: для каждого слова проверяем, видели ли мы его раньше, и либо увеличиваем счётчик, либо заводим новый.
Python 3.13text = "one two one two three" words = text.split() counts = {} for word in words: if word in counts: counts[word] = counts[word] + 1 else: counts[word] = 1 print(counts){'one': 2, 'two': 2, 'three': 1}
Здесь как раз помогает get() со значением по умолчанию: «возьми текущий счётчик, а если слова ещё не было — считай, что был ноль». Условие if/else сворачивается в одну строку.
Python 3.13text = "one two one two three" words = text.split() counts = {} for word in words: counts[word] = counts.get(word, 0) + 1 print(counts){'one': 2, 'two': 2, 'three': 1}
Что годится в ключи
Ключи живут по двум правилам, и оба следуют из того, как словарь устроен внутри.
- Ключи уникальны. Записать два одинаковых ключа нельзя: второе присваивание просто перезапишет первое. Это логично — иначе по ключу "Mary" было бы непонятно, какое из значений возвращать.
- Ключ должен быть неизменяемым. Подходят строки, числа, кортежи. Список ключом быть не может: Python находит значение по ключу через его неизменяемое содержимое, а список можно поменять уже после того, как он стал ключом, и значение «потеряется».
Python 3.13# Список в роли ключа — ошибка broken = {[1, 2]: "value"} # TypeError: unhashable type: 'list'
Значения же могут быть любыми: числа, строки, списки и даже другие словари.
Проверка понимания
Что выведет print(person["phone"]), если в словаре person нет ключа "phone"?
