[МУЗЫКА] [МУЗЫКА] Итак,
мы разобрались, как устроены множества внутри.
Конечно, это не совсем правда, но для понимания достаточно.
Теперь давайте научимся пользоваться ими.
Первое, что мы хотим научиться делать, — это создавать константное множество,
то есть записывать элементы множества прямо в тексте программы.
Например, так будет выглядеть множество, состоящее из чисел 1, 2, 3.
Давайте посмотрим, что хорошего можно сделать с двумя множествами,
и убедимся, что порядок элементов не играет никакой роли.
Мы создаем первое и второе множество, содержащее одни и те же элементы,
заданные в разном порядке.
Забегая вперед немного, я скажу,
что множество можно сравнивать на равенство — неравенство.
И сейчас мы посмотрим, равны эти два множества, или нет.
Для этого мы используем обычную операцию сравнения,
два значка «равно», и ожидаем получить результат true или false.
Результат оказался true, то есть результат сравнения этих множеств — это истина.
Множества равны, и порядок элементов действительно не играет никакой роли.
Как и во многих других объектах, для создания множеств
существуют другие способы, кроме задания их в виде констант,
в частности, функция set, которая умеет принимать что угодно
итерируемое на вход и возвращать множество, содержащее эти элементы.
Например, мы можем считать список чисел с клавиатуры и сделать из него множество.
То есть мы делаем список,
пользуемся стандартным способом для чтения
списка чисел и затем сделаем из него множество.
Напомню, что в множество элементы входят по одному разу,
то есть у нас должны остаться только уникальные элементы.
Что мы для этого делаем?
Создаем отдельную переменную и вызываем функцию set от нашего считанного списка.
В принципе, мы могли не делать его даже списком.
Мы проверим это чуть позже.
Потому что map нам и так вернет итерируемый объект.
Итак, давайте введем какие-нибудь числа: 1, 2, 1, например,
с повтором и какие-нибудь числа побольше — очень побольше.
И посмотрим, что у нас напечатается.
Итак, во-первых, печатается точно так же, как задается в тексте программы: это
фигурные скобки и элементы множества, перечисленные через запятую.
Во-вторых, что мы сейчас видим?
Что у нас никаких повторов нет, то есть 1,
встречавшаяся два раза, осталась в одном экземпляре.
И в-третьих, порядок никакой тут не присутствует,
то есть числа все идут вперемешку.
Если вы будете использовать только маленькие числа, то у вас они, возможно,
при выводе будут упорядочены.
Но это связано с тем, как элементы хранятся в множестве,
то есть если мы берем остаток по модулю какого-то не очень большого числа,
то естественно, если все числа меньше его, будут упорядочены.
Но в целом, в множествах на это рассчитывать никак нельзя.
Итак, давайте проверим, будет ли оно работать,
если мы не будем делать из этого список.
Я думаю, в этот раз мы обойдемся маленькими числами.
И действительно оно работает.
То есть в принципе, функцию set вы можете вызывать от чего угодно,
что умеет итерироваться по своим объектам.
Например, map возвращает iterable.
И умеет применять нашу функцию int последовательно к элементам списка,
который у нас считывается: строка и разрезается.
Вот этот список, к нему мы будем последовательно применять каждый раз,
когда нам нужен очередной элемент.
Это может быть функция range, это может быть строка, это может быть кортеж.
В общем, это может быть что угодно,
из чего можно доставать элементы последовательно.
Теперь давайте посмотрим, что еще хорошего можно сделать со множествами,
что туда можно класть, а чего туда класть нельзя.
Можно класть неизменяемые объекты.
Мы знаем, что это числа, вещественные числа, строки и кортежи.
Причем класть их можно в абсолютно произвольных сочетаниях,
то есть мы в одно множество можем положить и целые числа, и вещественные,
и какие-то строки, и даже кортежи,
например, такой.
И теперь можем всё это посмотреть,
как оно туда одновременно легло и как оно не упорядочилось.
Порядок опять же случайный.
При этом изменяемые объекты класть в множество нельзя.
Мы про это уже говорили, они не имеют хеша, не подсчитываются,
поэтому в множество они попасть не могут, и вот у нас возникает ошибка.
Собственно, здесь и написано: unhashable type list,
то есть не хешируемый, для него нет хеш-функции.
Множество при этом тоже является изменяемым объектом.
То есть внутри множества, элементом его не может быть другое множество.
Сейчас мы должны увидеть по идее ту же ошибку.
Но есть одна замечательная штука, которая называется frozenset.
Frozen — это замерзший.
То есть он задается и не изменяется.
Он — замороженный, его состояние не может измениться.
Но пока что мы не меняли состояние обычных set, но мы научимся.
Давайте посмотрим, может ли frozenset быть элементом обычного set.
[БЕЗ_ЗВУКА] Да,
frozenset может, записывается без подчеркивания, как и всё в Python.
Что такое frozenset?
То же самое, что и множество,
только которое не способно измениться никаким образом.
Таким образом, frozenset, поскольку он создается один раз и больше не меняется,
может иметь хеш, то есть хеш может быть подсчитан каким-то,
может быть, хитрым способом — нам это не так важно,
и исходя из этого, может быть элементом даже обычного множества.
Естественно, он может быть элементом frozenset.
Во frozenset точно так же не может быть никаких изменяемых объектов.
Почему?
По той же самой причине.
Потому что как только изменяемый объект изменяется,
мы должны пересчитать его хеш, удалить старую копию, добавить новую, и всё это
происходит очень медленно и поэтому не происходит, недопустимо на языке Python.
Когда мы печатаем
frozenset, в принципе,
мы можем вызвать эту функцию от обычного нашего set и сделать из него frozenset.
Это допустимо, но, конечно, будет достаточно медленно происходить.
У нас печатается слово frozenset, и когда мы просто set печатаем,
множество всех элементов, давайте сделаем его какое-нибудь более однородное,
у нас печатается всё в фигурных скобках и через запятую.
Какие есть способы избавиться от этого?
Давайте попробуем (программирование — наука экспериментальная),
посмотрим, поможет ли нам звездочка.
Да, звездочка нам помогла, и на маленьких числах они даже вывелись отсортированными.
То есть если вы хотите в задаче какой-то вывести все элементы множества,
то самый простой способ — это воспользоваться звездочкой так же,
как мы это делали с циклом, со списком.
Второй способ вывести множество.
Давайте подберем что-нибудь, чтобы порядок наконец-то перестал быть правильным.
Вот я подобрал такой порядок, такие числа, что их порядок при выводе — неправильный.
А теперь я хочу вывести их в порядке неубывания, то есть отсортированными.
Это довольно часто возникающая задача.
Что мы можем сделать?
Мы можем сделать из множества список, воспользовавшись обычной функцией list.
То есть множество — это такой мешок, откуда мы можем вытаскивать элементы в
каком-то случайном порядке и складывать их в список,
где они окажутся опять же записаны в этом случайном порядке.
А потом возьмем и отсортируем этот список.
Посмотрим.
Вот теперь у нас они упорядочены, и если мы хотим
вывести их красиво, достаточно добавить звездочку.
Еще одно достаточно частое применение множеств — это
подсчет количества различных букв в строке.
То есть вы можете взять строку и вызвать от нее функцию set.
И теперь мы можем, например, узнать,
а сколько различных букв у нас было в этой строке.
Для этого мы пользуемся стандартной функцией len, которая может вернуть
количество элементов, и она же подходит и для множеств.
То есть в множестве мы тоже можем узнать, сколько у нас там элементов хранится.
Поехали.
Итак, вот в этой строке четыре различные буквы, что похоже на правду.
Таким образом, главное, что нужно помнить,
что от чего угодно итерируемого вы можете вызвать функцию set и все повторяющиеся
элементы у вас исчезнут — останутся только уникальные.
В следующем видео мы научимся работать с отдельными элементами
множества и с несколькими множествами, сравнивать их как-то между собой,
складывать, объединять, вычитать, пересекать и многое другое.
[МУЗЫКА]
[МУЗЫКА]