Множество frozenset

Курс по стандартной библиотеке: https://stepik.org/a/259466?utm_source=proproprogs

Смотреть материал на YouTube | RuTube

Продолжаем изучение дополнительных типов данных языка Python и на этом занятии поговорим о способе создания множеств с помощью класса frozenset.

Вообще frozenset можно перевести с английского, как «замороженное множество». В действительности это неизменяемый аналог обычного множества set, о котором мы подробно говорили в базовом курсе по Python. Основное отличие frozenset от set заключается в том, что элементы «замороженного множества» нельзя изменять после его создания, тогда как обычное множество set позволяет добавлять, удалять и обновлять элементы динамически в процессе работы программы. То есть, frozenset относится к неизменяемым типам данных.

Создание frozenset

Для создания «замороженного множества» следует прописать класс frozenset и в круглых скобках указать итерируемый объект. Например, так:

fs = frozenset([1, 2, 3, 2, 3])

Получим множество fs с уникальными элементами 1, 2, 3. Или же можно использовать кортеж с набором данных:

t = ('a', 'b', True, 10, 'b')

и указать его при создании frozenset:

fs = frozenset(t)

Получим «замороженное множество» frozenset({'b', True, 10, 'a'}). Обратите внимание, что порядок следования элементов во frozenset может отличаться от исходного (переданного).

Или же можно передать строку, из символов которой будет сформировано множество:

fs = frozenset('abrakadabra') # frozenset({'b', 'k', 'a', 'r', 'd'})

Если не указывать ничего, то будет создано пустое множество:

f_empty = frozenset()

Таким образом, мы можем создавать множество frozenset на основе любого итерируемого объекта. Однако есть одно ограничение, которое касается и обычного множества set: все элементы множеств должны быть хэшируемыми, а значит, относиться к неизменяемым типам данных. Например, создать множество на основе следующего списка не получится:

lst = [1, [2, 3], {6, 5, 5}]
fs = frozenset(lst)

Увидим ошибку:

TypeError: unhashable type: 'list'

Действительно, список lst содержит два изменяемых объекта – это вложенный список [2, 3] и множество {6, 5, 5}.

Операции с frozenset

После того, как множество frozenset создано, с ним можно выполнять различные операции. Пусть для примера даны два множества:

s = {'abc', 10, -5.3, True}
f = frozenset(['a', 'b', 'c', 10, False])

Их можно объединить:

res_1 = f.union(s) # frozenset({False, True, 'abc', 10, 'b', 'a', -5.3, 'c'})
res_1 = f | s # аналог union()

- вычислить их пересечение:

res_2 = f.intersection(s) # frozenset({10})
res_2 = f & s # аналог intersection()

- вычислить их разность:

res_31 = f.difference(s) # frozenset({False, 'b', 'c', 'a'})
res_32 = s.difference(f) # {'abc', -5.3, True}
res_31 = f - s # аналог difference()
res_32 = s - f # аналог difference()

- вычислить симметричную разность (XOR):

res_4 = f.symmetric_difference(s) # frozenset({False, True, 'a', 'b', -5.3, 'c', 'abc'})
res_4 = f ^ s # аналог symmetric_difference()

Во всех этих операциях создаются новые множества, прежние остаются без изменений.

Операции сравнения frozenset

Дополнительно с множествами frozenset можно выполнять все стандартные операции сравнения. Пусть определены два следующих множества:

s = {1, 2, 3}
f = frozenset([1, 2, 3, 4])

Для них имеем:

s == f # False
f != s # True
s < f # True
f < s # False
f >= s # True
f <= s # False

Все эти операции сравнения работают по аналогии с обычными множествами, о которых мы подробно говорили в базовом курсе языка Python.

Применение множеств frozenset

Итак, мы с вами научились создавать множества типа frozenset и выполнять с ними различные операции. Однако остается вопрос, зачем понадобилось вводить этот новый тип данных? Что не хватало в базовом типе set? Ответ, в общем-то, очевиден. Так как frozenset относится к неизменяемым (хэшируемым) типам данных, то его можно использовать, например, в качестве ключей словаря, в то время, как обычное множество set не могло выступать в этой роли:

s = {1, 2}
f = frozenset([1, 2])
 
d1 = {f: 'frozenset'}
d2 = {s: 'set'} # ошибка TypeError: unhashable type: 'set'

Словарь d2 можно было бы сформировать путем замены обычного множества s на frozenset, например, так:

d2 = {frozenset(s): 'set'}

Мы здесь просто преобразовали изменяемое множество set к неизменяемому frozenset. В этом случае ошибок никаких нет. Или, используя моржовую операцию присваивания, можно дополнительно сохранить значение ключа в какой-либо переменной:

d2 = {(d2_key := frozenset(s)): 'set'}

В ряде случаев это бывает очень удобно.

Области применения

Вообще тип frozenset имеет смысл применять в следующих ситуациях:

  • когда нам нужны уникальные значения, но при этом нужно исключить случайные изменения в множестве;
  • использование в качестве ключей словарей;
  • при реализации структур данных, где важен порядок и неизменность объектов.

Таким образом, frozenset обеспечивает удобство хранения уникальных неизменяемых наборов данных, сохраняя возможность использования стандартных операций над множествами.

Курс по стандартной библиотеке: https://stepik.org/a/259466?utm_source=proproprogs

Видео по теме