Словари
Cписки и кортежи подходят для хранения последовательности элементов, но что если нам нужно получить элемент по какому-то имени или метке, а не по порядковому номеру? Для этого в Python существуют словари. Вместо того чтобы хранить элементы по порядку, словари хранят пары «ключ-значение». Это как настоящий словарь, где у каждого слова (ключ) есть свое определение (значение).
Давайте представим, что мы не знаем про словари, но хотим хранить имена людей и их номера телефонов. Тогда такая телефонная книга может выглядить как список кортежей:
phone_book = [
("Мастер", "+79315555555"),
("Маргарита": "+79637777777")
]
К каждому элементу такого списка следует обращаться по двойному индексу. Например, телефону Маргариты соответствует второй элемент второго кортежа:
print(phone_book[1][1])
# Вывод: +79637777777
Но согласитесь, что это не очень наглядно. Гораздо удобнее было бы обращаться к номеру телефона напрямую по имени человека, то есть получать значение словаря по ключу.
Создание словаря
Словарь, как и другие коллекции, можно создать двумя способами: с помощью скобок и специальной функции. Однако создание словаря с помощью функции dict()
может выглядить немного сложнее, чем в случае аналогичных функций для других коллекций, так как ей недостаточно просто передать другую коллекцию.
Создание словаря: фигурные скобки
В самом простом случае словарь создается с помощью фигурных скобок {}
, внутри которых через запятую перечисляются пары ключ: значение
. При этом ключ от значения отделяется с помощью двоеточия:
phone_book = {
"Мастер": "+79315555555",
"Маргарита": "+79637777777"
}
Создание словаря: функция dict()
Функция dict()
позволяет создать словарь из пар «ключ-значение», которы допускается передавать либо в виде именованных аргументов ключ=значение
, либо в виде последовательности кортежей с парами (ключ, значение)
.
Функция | dict(key1=value1, key2=value2,...) dict([(key1, value1), (key2, value2),...]) |
Описание | Создаёт словарь из именованных аргументов или последовательности кортежей |
Параметры | key=value – именованные аргументы ключ=значение (key, value) – кортежи с парами (ключ, значение) |
Возвращаемое значение | Словарь |
Создание словаря с помощью именованных аргументов
Именованные аргументы – это способ передавать данные в функцию таким образом, чтобы указать именно какому параметру должно соответствовать каждое значение. Например, мы уже использовали их, когда явно указывали разделитель sep
в функции print()
:
print(1, 2, 3, sep="-")
# Вывод: 1-2-3
Использование именованных аргументов предоставляет возможность передать пары «ключ-значение» непосредственно внутри самой функции dict()
:
phone_book = dict(Master="+79315555555", Margarita="+79637777777")
print(phone_book)
# Вывод:{"Master": "+79315555555", "Margarita": "+79637777777"}
Тогда сами именованные аргументы становятся ключами словаря, а из значения – значениями словаря.
Однако так как имена переменных, в том числе, параметров функции, могут содержать только английские буквы, то и ключи в таком словаре будут написаны английскими буквами.
Создание словаря из последовательности кортежей
Еще одним удобным способом создания словаря в Python является передача функции dict()
последовательности (например, списка или кортежа) кортежей, где каждый внутренний кортеж состоит из двух элементов: ключа и соответствующего ему значения:
phone_book_list = [
("Мастер", "+79315555555"),
("Маргарита", "+79637777777")
]
phone_book = dict(phone_book_list)
print(phone_book)
# Вывод: {'Мастер': '+79315555555', 'Маргарита': '+79637777777'}
Создание словаря из двух последовательностей
Однако часто бывает ситуация, когда у нас есть две отдельные последовательности: одна содержит ключи, другая – соответствующие значения. Чтобы объединить их в единый словарь, можно воспользоваться специальной функцией zip()
, которая попарно объединяет элементы нескольких последовательностей.
Функция | zip(keys, values) |
Описание | Возвращает последовательность кортежей, в котором первый элемент взят из коллекции keys , а второй – из коллекции values |
Параметры | keys – список, кортеж или множество ключей словаряvalues – список, кортеж или множество значений словаря |
Возвращаемое значение | Последовательность кортежей (ключ, значение) |
zip()
выглядит так:
- Создать отдельно списки (или любые другие последовательности) ключей и значений.
- Использовать функцию
zip()
для объединения этих последовательностей. - Передать полученный объект в функцию
dict()
, чтобы создать словарь.
names = ["Мастер", "Маргарита"]
phones = ["+79315555555", "+79637777777"]
phone_book = dict(zip(names, phones))
print(phone_book)
# Вывод: {'Мастер': '+79315555555', 'Маргарита': '+79637777777'}
Обе входные последовательности (ключей и значений) должны иметь одинаковую длину. Если длины различаются, лишние элементы будут проигнорированы:
students = ["Курчатов И.В.", "Сахаров А.Д.", "Харитон Ю.Б."]
grades = [
{"Теплотехника": 4, "Химия": 5},
{"Теплотехника": 5, "Химия": 4}
]
students_dict = dict(zip(students, grades))
print(students_dict)
# Вывод: {'Курчатов И.В.': {'Теплотехника': 4, 'Химия': 5}, 'Сахаров А.Д.': {'Теплотехника': 5, 'Химия': 4}}
Создание пустого словаря
Функция dict()
без аргументов или пустые фигурные скобки {}
создают пустой словарь:
emperors_achievements = dict()
emperors_achievements = {}
Доступ к элементам словаря
Обращение к элементам словаря похоже на обращение к элементам списка или кортежа, но вместо индекса в квадратных скобках следует указывать ключ:
subjects = {
"Математика": "Mathematics",
"Физика": "Physics",
"Информатика": "Informatics"
}
print(subjects["Математика"])
# Вывод: Mathematics
Как и в случае обращения по несуществующему индексу будет вызвано исключение IndexError, так и при обращении по несуществующему ключу словаря будет вызвано исключение KeyError (с англ. – Ошибка ключа):
print(subjects["Русский язык"])
# Ошибка: KeyError: 'Русский язык'
Избежать исключение KeyError позволяет метод dict.get()
, который в случае отсутствия ключа в словаре возвращает значение по умолчанию.
Метод | dict.get(key, default=None) |
Описание | Возвращает значение из словаря dict по ключу key |
Параметры | key – ключ, по которому требуется получить значениеНеобязательные параметры: default – значение, которое будет возвращено, если ключ key отсутствует в словаре dict , по умолчанию default=None |
Возвращаемое значение | Значение по ключу key или по умолчанию |
Теперь ещё раз получим перевод слова по несуществующему ключу:
print(subjects.get("Русский язык"))
# Вывод: None
В таком случае метод dict.get()
возвращает значение default
, которое по умолчанию равно None
.
Изменим возвращаемое значение с None
на "Отсутствует перевод слова"
, указав новое значение параметра default
:
print(subjects.get("Русский язык", "Отсутствует перевод слова"))
# Вывод: Отсутствует перевод слова
Вложенный словарь
Часто бывает недостаточно простого одноуровневого словаря, особенно когда приходится обрабатывать сложные структуры данных, такие как информация о людях, компаниях или товарах. Поэтому на помощь приходят вложенные словари, внутри которых содержатся другие словари. Это позволяет создавать иерархические данные, похожие на дерево, где каждый уровень соответствует какому-то уровню детализации информации. Например, в библиотеке нам может понадобиться хранить информацию о книгах по жанрам и авторам:
books = {
"Научная фантастика": {
"Кир Булычев": {
"Сто лет тому вперед": {
"Описание": "Приключения Алисы Селезнёвой",
"Год издания": 1976,
},
"Любовь к трём цукербринам": {
"Описание": "История любви и технологий будущего",
"Год издания": 2010,
}
}
},
"Историческая литература": {
"Борис Акунин": {
"Коронация": {
"Описание": "Приключения Эраста Фандорина",
"Год издания": 2000,
}
}
}
}
Чтобы обратиться к элементу вложенного словаря, нужно последовательно указывать ключи, начиная от внешнего уровня внутрь. Например, если нам надо получить информацию о романе Бориса Акунина "Коронация"
, то запись будет выглядить следующим образом:
info = books_database["Историческая литература"]["Борис Акунин"]["Коронация"]
# Вывод: {'Описание': 'Приключения Эраста Фандорина', 'Издательство': 'Захаров', 'Год издания': '2000'}
Добавление и изменение элементов словаря
Для добавления нового элемента в словарь достаточно присвоить новое значение по новому ключу:
goods = {
"Телевизор": 12500,
"Стиральная машина": 31999
}
goods["Холодильник"] = 38499
print(phone_book_dict)
# Вывод: {"Телевизор": 12500, "Стиральная машина": 31999, "Холодильник: 38499}
Поскольку ключ может соответствовать только одному значению, если вы несколько раз добавите значение ключу, последующие значения вытеснят предыдущие значения:
goods["Холодильник"] = 45000
print(goods["Холодильник"])
# Вывод: 45000
goods["Холодильник"] = 29999
print(goods["Холодильник"])
# Вывод: 29999
Словарь можно дополнить элементами другого словаря с помощью метода dict.update()
.
Метод | dict.update(dict2) |
Описание | Дополняет словарь dict новыми ключами из словаря dict2 и перезаписывает существующие ключи новыми значениями. |
Параметры | dict2 – словарь, все элементы которого требуется добавить в словарь dict |
Возвращаемое значение | None |
Данный метод изменяет исходный словарь, но оставляет без изменений тот, чьими значениями он дополняется:
rooms = {
"Комната 12А": "Алексей",
"Комната 12Б": ["Кирилл", "Денис"]
}
girls_rooms = {
"Комната 13А": "Полина",
"Комната 13Б": "Наталья"
}
rooms.update(girls_rooms)
print(rooms)
# Вывод: {"Комната 12А": "Алексей", "Комната 12Б": ["Кирилл", "Денис"], "Комната 13А": "Полина", "Комната 13Б": "Наталья"}
Удаление элементов словаря
Удалить элементы словаря можно с использованием оператора del
, после которого указывается элемент по ключу:
flower_meanings = {
"Хризантема": ["Дружба", "Правда"],
"Кактус": "Схожесть характеров",
"Примула": "Объяснение в любви"
}
del flower_meanings["Хризантема"]
# Вывод: {"Кактус": "Схожесть характеров", "Примула": "Объяснение в любви"}
Также удалить элемент по ключу позволяет метод dict.pop()
, который как и в случае списков и множеств, не просто удаляет элемент, но и возвращает его.
Метод | dict.pop(key, default=None) |
Описание | Удаляет и возвращает из словаря dict элемент по ключу key |
Параметры | key – ключ элемента, который требуется удалитьНеобязательные параметры: default – значение, которое будет возвращено, если ключ key отсутствует в словаре dict , по умолчанию default=None |
Возвращаемое значение | Удаляемое значение по ключу key |
Так мы можем вывести уведомление об удаленном элементе:
flower_meanings = {
"Хризантема": ["Дружба", "Правда"],
"Кактус": "Схожесть характеров",
"Примула": "Объяснение в любви"
}
deleted_flower_meanings = flower_meanings.pop("Кактус")
print(f"Было удалено значение: {deleted_flower_meanings}")
# Было удалено значение: Схожесть характеров
print(flower_meanings)
# Вывод: {"Примула": "Объяснение в любви"}
В отличие от значения по умолчанию в методе dict.get()
, которое если не задано, то возвращает None
, метод dict.pop()
вызывает исключение KeyError, если ключ отсутствует в словаре и значение по умолчанию не задано.
1. Чем словарь отличается от списка?
2. Дан словарь: food = {"Яблоки красные": "78 руб/кг", "Картофель свежий": "83 руб/кг", "Помидоры красные": "120 руб/кг"}
. Напишите программу, которая выводит на экран цены за 1 кг красных яблок и за 1 кг жёлтых груш. Если в словаре нет данных о стоимости какого-то продукта, то программа должна выводить строку "Нет данных"
.
3. Дан словарь: capitals = {"Вологодская область": "Череповец", "Республика Татарстан": "Казань", "Республика Саха": "Якутск", "Германия": "Берлин"}
. Напишите программу, которая изменяет столицу Вологодской области с "Вологда"
на "Череповец"
и удаляет элемент с ключом "Германия"
. Полученный словарь должен быть выведен на экран.
4. Дан список кортежей: team = [("Иван", 25), ("Мария", 30), ("Петр", 28)]
. Напишите программу, которая преобразует этот список в словарь, где ключами будут имена, а значениями – возраст. Полученный словарь должен быть выведен на экран.
5. Даны два списка: numbers = list(range(1, 6))
и english_words = ["One", "Two", "Three", "Four", "Five"]
. Напишите программу, которая создаёт словарь, в котором ключи – числа от 1 до 5 (список numbers
), а значения – перевод этих чисел на английский язык (список english_words
). Полученный словарь должен быть выведен на экран.