Задача №3. Словари и их свойства. Списковое включение
Рекомендации
Перед тем, как приступить к разбору решения, попробуйте решить задачу самостоятельно, предварительно изучив новый материал о словарях.
Условие задачи
Внимательно прочтите условие задачи и скопируйте в среду разработки.
# Поиск самых высокооплачиваемых работников
# Дан словарь, в котором нужно найти всех сотрудников,
# зарабатывающих по крайней мере 100 000 долларов в месяц.
employees = {
'Alice' : 100000,
'Bob' : 99817,
'Carol' : 122908,
'Frank' : 88123,
'Eve' : 93121
}
Словари dict
Вы заметили, что в задаче используется новый тип данных - словари dict
. Словарь - это коллекция, в которой неупорядоченно хранятся ключи и связанные с ними элементы.
Достоинством словарей является скорость поиска. Например, чтобы найти элемент в списке, интерпретатору необходимо перебирать элементы до тех пор, пока не попадется искомый элемент. Скорость поиска в словаре постоянна, то есть каждому значению однозначно присвоен один ключ. Словари в Python являются реализацией хеш-таблиц, подробнее о которых вы можете прочитать по ссылке.
Рассмотрим некоторые операции со словарями. Для создания словарей используются фигурные скобки {}
внутри которых хранятся пары ключ : значение
.
# Примеры словарей
vocabulary = {'а' : 'ананас', 'б' : 'брюква'}
# или с переносом на другие строки
vocabulary = {
'а' : 'ананас',
'б' : 'брюква'
}
# Пустой словарь
empty_dct = {}
# или
empty_dct = dict()
Словарь является изменяемым типом данных и в него можно добавлять новые ключи. Создадим пустой словарь capitals
, который будет хранить страны и столицы.
capitals = {}
# Добавление элементов в словарь
capitals['Россия'] = 'Москва'
capitals['Франция'] = 'Париж'
# обращение к ключу словаря возвращает элемент
print(capitals['Россия'])
Обращение к значению по ключу в словаре похоже на операцию индексации в списках, только вместо числового индекса используется ключ. Ключом может быть любой неизменяемый тип данных, то есть списки, словари и множества ключами быть не могут! Значением может быть любой тип данных.
Рассмотрим полезные методы словарей. Не забывайте, что список методов можно вывести с помощью функции dir()
.
# получить ключи словаря
capitals.keys()
# получить значения
capitals.values()
# получить пары "ключ:значение"
capitals.items()
# получить значение по ключу "Италия", если такого ключа нет - вернуть "Отсутствует"
capitals.get('Италия', 'Отсутствует')
# получить значение по ключу 'Италия', если такого ключа нет - добавить в словарь "'Италия':None"
capitals.setdefault('Италия')
Решение
Вариант решения 1
Теперь мы знаем, что для того, чтобы получить значение в словаре, надо обратиться к его ключу. Словарь employees
в своих значениях хранит денежные суммы, которые надо сравнить с пороговым значением 100к$.
Воспользуемся циклом for
, для того чтобы получить каждый ключ по отдельности через метод словарей keys()
. Следовательно, по каждому ключу получим значение, результат сравнения с которым выведем в консоль. Обратите внимание, что вместо i
используется name
, так как данная переменная лучше отражает суть того, что она хранит.
Для двух имен мы получили True
: для Alice и Carol. Теперь добавим их в новый список, согласно условию задачи. Для этого опишем фильтрующее условие if
и создание и обработку нового списка top_mgrs.
# Пустой список топ-менеджеров
top_mgrs = []
# перебираем ключи и сравниваем значения зп с порогом 100к$
for name in employees.keys():
if employees[name] >= 100000:
top_mgrs.append(name)
# вывод в консоль
print(f"Топ-менеджеры: {top_mgrs}")
В результате, мы получаем список сотрудников у которых заработная плата больше 100к$.
Обратите внимание, что решение довольно простое, но занимает несколько строк кода. В следующем параграфе рассмотрим способ записи такого решения короче.
Списковые включения
Если в Python необходимо применить простое фильтрующее условие для обработки списка или словаря, то можно воспользоваться однострочной записью некоторых операторов, например for
и if
.
Однострочная запись if
Например, имеем следующее условие.
Запись в одну строку выглядит следующим образом.
Выражение для истинного условия записывается слева, а для ложного записывается справа.
Однострочная запись for
Например, имеем список, каждое значение в котором нужно умножить на 2.
Запись в одну строку выглядит следующим образом.
В данном случае:
for i in [1, 2, 3, 4, 5]
- цикл, который перебирает числа в списке,i*2
- выражение, которое надо выполнить каждого i из цикла,[ ... ]
- список, внутри которого происходят вложенные операции,print()
- функция, которая выводит результат в консоль.
Списковые включения list comprehension
- это сокращенная запись для обработки списков по заданному условию. Список как бы "генерируется внутри" из исходного списка. Также существуют словарные сборки и генераторные сборки - сокращенные записи на основе словарей и кортежей, соответственно.
Ниже приведены примеры применения списковых включений.
# Создание списка квадратов чисел
squares = [x**2 for x in range(10)]
print(squares)
# Выборка нечетных чисел в заданном диапазоне:
odds = [x for x in range(10) if x%2 != 0]
print(odds)
Вариант решения 2
Рассмотрим однострочный вариант решения задачи про сотрудников. Запишем списковое включение, которое перебирает все ключи словаря employees
.
Обратите внимание, что ключи из employees
можно получить без применения метода keys()
. Переменная n
- это сокращение от name, так как решение, представленое в одну строку, ограничено по длине используемых переменных.
Добавим условие if в записанное списковое включение. Такие условие записываются после for!
Из словаря можно получить пары ключ:значение
используя метод item()
, что позволит убрать обращение по ключу. Таким образом однострочное решение будет выглядеть следующим образом.
# списковое включение перебирает ключи и сравниваем значения зп с порогом 100к$
top_mgrs = [n for n,s in employees.items() if s>=100000]
# вывод в консоль
print(f"Топ-менеджеры: {top_mgrs}")
В результате, мы получаем список сотрудников у которых заработная плата больше 100к$.