Решение задач с помощью словарей
Словари в Python удобно использовать для решения задач, связанных с:
- хранением и обработкой данных о свойствах объекта;
- сопоставлением данных;
- подсчетом;
- выбором подходящих по условию значений – включая регулярные выражения.
В последнем случае словарь эффективно заменяет условные конструкции if – elif – else. В качестве ключей в словарях можно использовать только неизменяемые типы данных – цифры, строки (включая «сырые») и кортежи. Однако в качестве значений можно использовать почти любые типы данных.
Задача 1: Скрабл
В настольной игре Скрабл (Scrabble) каждая буква имеет определенную ценность. В случае с английским алфавитом очки распределяются так:
- A, E, I, O, U, L, N, S, T, R – 1 очко;
- D, G – 2 очка;
- B, C, M, P – 3 очка;
- F, H, V, W, Y – 4 очка;
- K – 5 очков;
- J, X – 8 очков;
- Q, Z – 10 очков.
А русские буквы оцениваются так:
- А, В, Е, И, Н, О, Р, С, Т – 1 очко;
- Д, К, Л, М, П, У – 2 очка;
- Б, Г, Ё, Ь, Я – 3 очка;
- Й, Ы – 4 очка;
- Ж, З, Х, Ц, Ч – 5 очков;
- Ш, Э, Ю – 8 очков;
- Ф, Щ, Ъ – 10 очков.
Напишите программу, которая вычисляет стоимость введенного пользователем слова. Будем считать, что на вход подается только одно слово, которое содержит либо только английские, либо только русские буквы.
Пример ввода:
ноутбук
Пример вывода:
12
Решение:
Сначала напишем функцию isCyrillic()
, которая возвращает True
, если введенное слово содержит кириллические символы, и False
, если буквы – латинские.
Затем создадим словари, где ключами будут очки, а значениями – строки из букв. Метод items()
позволяет обращаться к ключам и значениям одновременно – если очередная буква в слове входит в одно из значений, генератор добавит ключ в список, а метод списка sum()
подсчитает стоимость всего слова:
Хочешь научиться создавать программы и автоматизировать рутинные задачи на Python? На нашем курсе ты не только изучишь синтаксис языка, но и научишься мыслить как программист, решая реальные задачи и создавая полноценные приложения.
Что ты получишь:
- Структурированную программу обучения, подходящую даже для новичков
- Практические задания, позволяющие закрепить теорию
- Поддержку опытных преподавателей
- Возможность создать свой первый проект уже во время обучения
Задача 2: Рюкзак
Турист собирается в поход. Он сможет нести N
кг вещей. Но вещей, которые он запланировал уложить в рюкзак, оказалось намного больше. Нужно определить, какие вещи от наиболее тяжелых к самым легким поместятся в рюкзак.
Пример ввода:
10
Пример вывода:
палатка
спальный мешок
удочка
термос
салфетки
жвачка
Решение:
Эту классическую задачу комбинаторной оптимизации удобно решать с помощью словаря, в котором содержатся все вещи. Для сортировки вещей мы воспользуемся методом sorted()
и лямбда-функцией в качестве ключа сортировки. Решение выглядит так:
Задача 3. Email-адреса
Данные об email-адресах студентов хранятся в словаре:
Нужно дополнить код таким образом, чтобы он вывел все адреса в алфавитном порядке и в формате имя_пользователя@домен
.
Решение:
Задача решается с помощью генератора словаря (или списка) и метода sorted()
в одну строчку:
Задача 4: Права доступа
Вирус повредил систему прав доступа к файлам. Известно, что над каждым файлом можно производить определенные действия:
- запись –
W
; - чтение –
R
; - запуск –
X
.
На вход программе подается:
- число
n
– количество файлов; n
строк с именами файлов и допустимыми операциями;- число
m
– количество запросов к файлам; m
запросов вида «операция файл».
Для каждого допустимого запроса программа должна возвращать OK
, для недопустимого – Access denied
.
Пример ввода:
3
python.exe X
book.txt R W
notebook.exe R W X
5
read python.exe
read book.txt
write notebook.exe
execute notebook.exe
write book.txt
Пример вывода:
Access denied
OK
OK
OK
OK
Решение:
Для сопоставления соответствия команд правам доступа создадим словарь rights, для записи введенных имен – словарь names. Конструкция print(('Access denied', 'OK')[comm in names[n]])
, которая выводит результат, аналогична print('OK' if comm in names[n] else 'Access denied')
и заменяет цикл с условием:
Задача 5: Продажи
Напишите программу, которая подсчитывает количество единиц товаров, приобретенных покупателями онлайн-магазина. На вход программе подается число n – количество записей о покупках, а затем n строк вида «Покупатель Товар Количество». Для каждого покупателя программа должна выводить список покупок.
Пример ввода:
5
Сергей Карандаш 3
Андрей Тетрадь 5
Юлия Линейка 1
Сергей Ручка 2
Юлия Книга 4
Пример вывода:
Андрей:
Тетрадь 5
Сергей:
Карандаш 3
Ручка 2
Юлия:
Книга 4
Линейка 1
Решение:
Проще всего такую задачу решить с помощью метода setdefault()
– он позволяет получить значение из словаря по заданному ключу, и автоматически добавляет в словарь отсутствующие там элементы:
Задача 6: Объединение словарей
В Python предусмотрено объединение словарей:
merged_dict = {**dict1, **dict2}
Однако если в словарях есть одинаковые ключи, ключу в объединенном словаре будет присвоено значение из второго словаря. Напишите программу, которая объединяет два словаря и суммирует значения одинаковых ключей.
Решение:
Воспользуемся методом get()
, который принимает второй аргумент – значение по умолчанию, в нашем случае это должен быть 0
. Кроме того, применим объединение множеств с помощью оператора |
:
Задача 7: Коты и владельцы
В базе данных ветеринарной клиники информация о пациентах-котах хранится в списке кортежей. Данные о кошках и их владельцах записаны в формате «Кличка животного, Возраст животного, Имя владельца, Фамилия владельца»:
Обнаружилось, что имена некоторых владельцев повторяются, потому что у них несколько кошек. Необходимо оптимизировать хранение данных таким образом, чтобы для каждого владельца при выводе на печать данные о всех его животных отображались в одной строке:
Игорь Бероев: Муся, 7; Изольда, 2
Решение.
Воспользуемся методом словарей setdefault()
и методом join()
для объединения элементов списков и кортежей с необходимыми разделителями:
Задача 8: Редкое слово
Напишите программу, которая принимает на вход строку, и выводит слово, которое встречается во фразе реже всего. Если редких слов несколько, нужно вывести то, которое меньше в лексикографическом порядке. Регистр слов не учитывается, знаки препинания в предложениях игнорируются.
Пример ввода:
дом, милый дом, милый.
Пример вывода:
дом
Решение:
Для подсчета символов, слов и т. п. удобно использовать метод get()
, а для сортировки – лямбда-функцию, которая обеспечит вывод наименьшего из редких слов:
Задача 9: Дубликаты
Напишите программу, которая принимает на вход строку, и отслеживает, сколько раз каждый символ уже встречался. Количество повторов добавляется к символам с помощью постфикса формата _n
.
Пример ввода:
a a a b c a a d c d d
Пример вывода:
a a_1 a_2 b c a_3 a_4 d c_1 d_1 d_2
Решение:
Самое компактное решение получается при использовании f-строк
и метода get()
:
Задача 10: Анаграммы
Напишите программу, которая принимает на вход две строки и определяет, являются ли они анаграммами. Знаки препинания, пробелы и регистр при этом игнорируются.
Пример ввода:
Цари, вино и сало.
Лисица и ворона.
Пример вывода:
YES
Решение:
Избавиться от знаков препинания можно несколькими способами – с помощью strip()
, replace()
, или просто путем добавления в словарь только букв (метод isalpha()
) из введенных строк:
Задача 11: Расшифровка
На вход программе подается:
1. Зашифрованная строка.
2. N
– число букв в словаре.
3. N
строк, в которых в формате «буква: частота» указывается, сколько раз каждая буква встречается в слове.
Программа выводит расшифрованное слово.
Пример ввода:
?*!*!*
3
b: 1
a: 3
n: 2
Пример вывода:
banana
Решение:
Для сопоставления символов зашифрованного слова с буквами понадобятся два словаря:
Задача 12: Запрос
Напишите функцию, которая принимает словарь с параметрами и возвращает строку запроса, сформированную из отсортированных в лексикографическом порядке параметров.
Пример:
Код print(query({'course': 'python', 'lesson': 2, 'challenge': 17}))
должен возвращать строку:
challenge=17&course=python&lesson=2
Решение:
Используя метод items()
, функцию можно написать так:
Примечание – в Python есть библиотека urllib
для работы с параметрами URL. При использовании этого модуля функция выглядит так:
Другие варианты
Каждую из приведенных выше задач можно решить несколькими способами – с использованием словарей или без них. Генераторы сокращают код в несколько раз, но в то же время усложняют чтение – начинающим, возможно, будет проще использовать обычные циклы.
Комментарии