В этой главе мы рассмотрим один из самых важных встроенных типов данных, который приблизит вас к более профессиональной работе с коллекциями (наборами данных). Да и вообще, словари – это одна из лучших функций в python, которая помогает делать код более элегантным в исполнении.
Словари – это неупорядоченный, изменяемый набор элементов, в котором объекты находятся в паре ключ-значение. Это очень похоже на списки, однако вместо индексов в словаре используются ключи, которые нужно задавать самостоятельно.
В качестве примера отлично рассматривать реальные словари из жизни, в которых пара ключ-значение представлены словом и его объяснением.
Словари в python представлены отдельным типом dict, которому сопоставлена фукнция преобразования dict().
В отличие от списков, словари задаются фигурными скобками. После чего, внутри этих скобок, необходимо указать пару ключ-значение.
Ключ (key), как пракило, представляет собой строку (str)
Значение (value) может быть любым типом или ссылкой
Взаимодействие со словарями несколько отличается от списков. Так, чтобы добавить новую пару ключ-значение, достаточно обратиться к словарю, указать в [] новый ключ и через равно записать новое значение. Похоже на изменение по индексу в списках, не так ли? Кстати, если нужно изменить значение – запись будет такой же.
Как вариант, можно воспользоваться методом update, для добавления новых значений/изменения старых.
Чтобы удалить ключ, можно воспользоваться либо оператором del, либо методом pop, указав ключ, который вы хотите удалить.
Создайте файл workers_list.py
В этой программе вам нужно реализовать словарь сотрудников в некоторой организации. В качестве ключа будет указываться уникальный числовой идентификатор сотрудника, а в качестве значения – информация о нем. Информация должна быть в виде списка:
[ Имя, Фамилия, № рабочего места, должность, зарплата ]
Реализуйте несколько функций для работы со словарем. Основная часть программы должна спрашивать, какое действие хочет совершить пользователь и выполнить функцию согласно её описанию. Если пользователь напишет Q/q то программа должна завершить свою работу.
add_user()
В качестве параметра принимает словарь сорудников, который нужно будет изменить, а также последний id, который был использован. Поочередно спрашивает всю необходимую информацию. После чего под id+1 ключом вносит информацию в словарь.
Функция должна возвращать обновленный словарь и новый id
info_user()
В качестве параметра принимает словарь. Спрашивает через input, информацию о каком сотруднике надо вывести. Функция ничего не возвращает. Далее выводит отформатированную информацию в консоль, например:
Имя: Алексей
Фамилия: Кухарь
Должность: Менеджер по проектам
Зарплата: 950$
fire_user()
В качестве параметра принимает словарь. Спрашивает через input, какого сотрудника необходимо уволить. Не удаляет ключ, а заменяет список с информацией о нем на строку c timestamp (когда функция вызывается, с помощью модуля datetime узнает сегодняшнюю дату и пишет эту информацию в строку. Пример:
Уволен: 12.02.2023
Как думаете, в каком формате удобнее будет хранить информацию о сотруднике: в списке или в словаре? Почему?
Как и списки, словари являются итерируемыми объектами (помните ли вы, что такое итерация?). Это значит, что вы можете перебрать все объекта по ключам в словаре.
Так как словари крайне похожи на списки, то и у них, вероятно, будут методы, не так ли? Полный список вы можете найти в документации, а ниже вы найдете самые популярные из них:
fruits = { "Apple": 4, "Banana": 10, "Pineapple": 6 }
# Создает поверхностную копию, не подойдет, если в значениях хранятся изменяемые типы (списки, словари и тд) и нужно полностью копировать их тоже
fruits2 = fruits.copy()
# Возвращает значение ключа. Второй параметр - значение по умолчанию, если такой ключ не будет найден
f1 = fruits.get("Apple")
f2 = fruits.get("Kiwi", 0)
# Возвращает значение по ключу, как и get. Но если будет указан второй параметр, а ключа не будет - создаст ключ с этим значением
f2 = fruits.setdefault("Kiwi", 0)
# Возвращает все ключи
print(fruits.keys())
# Возвращает все значения
print(fruits.keys())
# Проверить, есть ли ключ в словаре, поможет оператор in
print("Apple" in fruits, "Pitahaya" in fruits)
# Очищает словарь
fruits.clear()
Продолжите работать в файле workers_list.py
В этом задании вы продолжаете работать с файлом. Ваша задача - добавить новые функции по описанию.
clear_workers()
Как и следует из названия - нужно реализовать метод очистки работников. Обязательно спросите, уверен ли пользователь в том, что хочет очистить список. Да - очищайте, нет - ничего не делайте.
max_salary()
Функция должна возвращать сотрудника с самой высокой зарплатой. С помощью цикла найдите такого сотрудника и выведите его имя на экран. Если таких сотрудников несколько, выведите их всех.
list_workers()
Выведите список всех сотрудников в алфавитном порядке. Для сортировки используйте метод sort для списка.
list_current_workers()
Выведите список всех сотрудников в алфавитном порядке, но в этот раз только тех, кто не уволен.
Словари в Python реализованы с помощью хеш-таблиц — особой структуры данных, которая обеспечивает быстрый доступ к значениям по ключам.
Основная идея проста: каждый ключ словаря пропускается через специальную функцию, называемую хеш-функцией. Эта функция возвращает число (хеш), на основе которого Python определяет, в какой ячейке словаря будет храниться связка «ключ—значение».
Представьте словарь как ряд ячеек памяти, каждая из которых может хранить пару «ключ—значение» или ссылку на неё.
Когда вы добавляете новый элемент, Python вычисляет hash("Apple"), чтобы найти, куда поместить эту пару.
Допустим, хеш от apple указывает на ячейку 2. Тогда связка («apple» → «4») попадает в соответствующую позицию.
Если какая-то другая пара уже заняла это место, словарь умно пытается подобрать следующую свободную ячейку по определённому алгоритму (технику разрешения коллизий).
Аналогично, при поиске значения по ключу:
f = fruits["Apple"]
Python снова возьмёт ключ, вычислит его хеш, выяснит, в какой ячейке ожидается нужная пара, и быстро найдёт соответствующее значение. Это делает доступ к элементам словаря практически мгновенным, независимо от его размера (в среднем, поиск и вставка в словарь происходят за время, близкое к постоянному).
Если при добавлении возникает «коллизия» (разный ключ даёт хеш, указывающий на уже занятую ячейку), словарь применяет стратегию, чтобы разместить новый элемент в другом месте. Например, словарь может «пробежать» по следующему ряду ячеек или использовать другую формулу для выбора новой позиции.
☝️Важно, что даже с коллизиями операции со словарями остаются очень быстрыми, и на практике вы редко замечаете или задумываетесь об этих механизмах.
Именно благодаря этой умной внутренней структуре словари в Python невероятно эффективны и удобны. Вам не нужно вручную управлять хеш-таблицами, разрешать коллизии или заботиться о скорости доступа к элементам — язык делает это за вас, позволяя сосредоточиться на логике программы.
Попробуйте ответить на ряд следующих вопросов:
Почему операции поиска, добавления и удаления в словаре обычно работают за время, близкое к константному?
Как изменение размера словаря (например, при добавлении большого количества новых элементов) влияет на структуру хеш-таблицы и распределение элементов?
Предположим, вы часто извлекаете значение по ключу из словаря. Почему производительность этих операций обычно не ухудшается сильно даже при значительном росте словаря?
Подумайте, как особенности хранения словаря в памяти могут влиять на расход памяти и производительность программы при работе с очень крупными наборами данных. Какие компромиссы могут возникать?
Ранее мы изучили множество типов данных, такие как списки, строки, словари и кортежи – все эти типы решают вопросы по организации данных. Теперь познакомимся с еще одним полезным инструментом – множествами (set).
Множества, как и в математике, – это коллекция уникальных, неупорядоченных элементов.
Главное, с чем помогают справиться множества – это удаление дублей, быстрой проверкой вхождения элементов и поддерживают привычные математические операции: объединение, пересечение и разность (помните ли вы, такие операции в школьном курсе математики или университете?).
Такие операции делают множества очень удобным стредством для фильтрации данных, гибкого поиска и манипуляций над набором элементов.
В этой части главы мы посмотрим, как создавать множества, применять к ним операции и решать с помощью них задачи.
Создать множество в Python можно несколькими способами. Самый простой из них — использовать фигурные скобки, аналогично тому, как мы определяем словари или множества в математике. Однако, в отличие от словарей, внутри фигурных скобок для множеств нет пар «ключ—значение»; мы просто перечисляем нужные элементы через запятую.
По классике, у множеств есть длина списка, а также вы можете проверять вхождение в множество через оператор in.
А добавить элемент можно через метод add.
Так как множества являются итерируемыми объектами, вы можете проходить по их элементам в цикле for. Порядок обхода не гарантирован, ведь множества неупорядоченны.
У множеств есть несколько способов удалить элементы:
discard(<элемент>) удалит элемент, если он есть в множестве, и просто проигнорирует операцию, если элемента нет. Таким образом, discard безопасен, когда мы не уверены в наличии элемента
remove(<элемент>) ведёт себя так же, как discard, но генерирует ошибку, если элемента нет в множестве. Применяйте remove(), когда вы уверены в наличии нужного элемента:
pop() удаляет и возвращает случайный элемент из множества. Если множество пусто, pop() вызовет ошибку. Этот метод может быть полезен, если порядок элементов не важен, а вам нужно «выгрести» их по одному:
Создайте файл repeated_elements.py
Напишите программу, в которой пользователь вводит два списка, элементы которого перечислены через пробел. Нужно посчитать, сколько элементов содержится и в первом списке, и во втором одновременно.
banana apple pear
pear kiwi apple
Повторяется элементов: 2
Создайте файл filtred_set.py
Напишите программу, в которой пользователь вводит список слов (через пробел) и затем вводит список слов для удаления из этого набора. Программа должна преобразовать первый список в множество, удалить из него элементы второго списка (также преобразованного в множество) и вывести результат.
Введите исходный список слов: apple banana cherry pear apple
Введите слова для удаления: apple pear kiwi
Множество после удаления: {'banana', 'cherry'}
Создайте файл extension_set.py
Напишите программу, в которой пользователь вводит множество слов (через пробел) и затем вводит ещё один список слов. Программа должна преобразовать первый ввод в множество, а второй ввод — в список (или тоже в множество), затем добавить все элементы второго ввода в первое множество и вывести итоговый набор.
Введите исходное множество слов: banana cherry
Введите слова для добавления: apple banana grape
Множество после добавления: {'apple', 'banana', 'cherry', 'grape'}
Создать множество в Python можно несколькими способами. Самый простой из них — использовать фигурные скобки, аналогично тому, как мы определяем словари или множества в математике. Однако, в отличие от словарей, внутри фигурных скобок для множеств нет пар «ключ—значение»; мы просто перечисляем нужные элементы через запятую.
Создайте файл intersection.py
Напишите программу, которая просит пользователя ввести два набора слов, перечисленных через пробел. Преобразуйте их в множества, найдите их пересечение и выведите результат.
Введите первый набор слов: apple banana cherry pear
Введите второй набор слов: banana grape apple mango
Результат: {'apple', 'banana'}
Создайте файл union.py
Напишите программу, в которой пользователь вводит три набора чисел через пробел. Программа должна преобразовать каждый ввод в множество, а затем найти объединение всех трёх множеств и вывести полученный результат.
Введите первый набор чисел: 1 2 3
Введите второй набор чисел: 3 4 5
Введите третий набор чисел: 5 6 7
Результат: {1, 2, 3, 4, 5, 6, 7}
Создайте файл is_come_across.py
Напишите программу, которая будет считывать числа от пользователя в строке через пробел. После программа должна вывести для каждого числа (по порядку), встречалось ли оно ранее или нет
Введите набор чисел: 10 5 10 3
Результат: NO NO YES NO
Множества (set) и словари (dict) в Python — это два фундаментальных типа данных, обеспечивающие гибкую и эффективную работу с коллекциями. Словари позволяют организовывать информацию в формате «ключ—значение», что делает их идеальным инструментом для быстрой выборки данных по именованным ключам. Вы можете мгновенно получать доступ к нужным фрагментам информации, обновлять их и дополнять новыми записями.
Множества, в свою очередь, представляют собой неупорядоченные коллекции уникальных элементов. Их сильная сторона — лёгкая фильтрация дублей, быстрая проверка наличия элемента и привычные операции множества из математики (пересечения, объединения, разности). Эти операции позволяют просто и элегантно решать широкий круг задач, связанных с разбором и классификацией данных.
Оба типа — словари и множества — отличаются высокой скоростью доступа к элементам благодаря хеш-таблицам «под капотом». Если вам нужно связать объекты по ключам, оптимизировать поиск, убрать дубликаты или выполнить массовые операции над наборами данных, словари и множества — ваш надёжный выбор. Они образуют прочный каркас, на котором можно строить эффективные и понятные программы на Python, используя их в сочетании с другими структурами данных и инструментами языка.