Тип set
– это разновидность коллекций, которая поддерживает оператор
проверки на вхождение in
, функцию len()
и относится к разряду
итерируемых объектов. Кроме того, множества предоставляют метод
set.isdisjoint()
и поддерживают операторы сравнения и битовые
операторы (которые в контексте множеств используются для получения
объединения, пересечения и т. д.). В языке Python имеется два
встроенных типа множеств: изменяемый тип set
и неизменяемый
frozenset
. При переборе элементов множества элементы могут следовать
в произвольном порядке.
В состав множеств могут включаться только хешируемые
объекты. Хешируемые объекты – это объекты, имеющие специальный метод
__hash__()
, на протяжении всего жизненного цикла объекта всегда
возвращающий одно и то же значение, которые могут участвовать в
операциях сравнения на равенство посредством специального метода
__eq__()
. (Специальные методы – это методы, имена которых начинаются
и оканчиваются двумя символами подчеркивания).
Все встроенные неизменяемые типы данных, такие как float
,
frozenset
, int
, str
и tuple
, являются хешируемыми объектами и
могут добавляться во множества. Встроенные изменяемые типы данных,
такие как dict
, list
и set
, не являются хешируемыми объектами,
так как значение хеша в каждом конкретном случае зависит от
содержащихся в объекте элементов, поэтому они не могут добавляться в
множества.
Множества могут сравниваться между собой с использованием стандартных
операторов сравнения (<
, <=
, ==
, !=
, >=
, >
). Обратите
внимание: операторы ==
и !=
имеют обычный смысл, и сравнение
выполняется путем поэлементного сравнения (или рекурсивно при наличии
таких вложенных элементов, как кортежи и фиксированные множества
(frozenset
)), но остальные операторы сравнения выполняют сравнение
подмножеств и надмножеств, как вскоре будет показано.
set
Тип set
– это неупорядоченная коллекция из нуля или более ссылок на
объекты, указывающих на хешируемые объекты. Множества относятся к
категории изменяемых типов, поэтому легко можно добавлять и удалять их
элементы, но, так как они являются неупорядоченными коллекциями, к ним
не применимо понятие индекса и не применима операция извлечения
среза. На рис. 3 иллюстрируется множество,
созданное следующим фрагментом программного кода:
S = {7, "veil", 0, -29, ("x", 11), "sun", frozenset({8, 4, 7}), 913}
Рисунок 3: Множество – это неупорядоченная коллекция уникальных элементов
Тип данных set
может вызываться как функция set()
–
без аргументов она возвращает пустое множество; с аргументом типа
set
возвращает поверхностную копию аргумента; в случае, если
аргумент имеет другой тип, выполняется попытка преобразовать его в
объект типа set
. Эта функция принимает не более одного
аргумента. Кроме того, непустые множества могут создаваться без
использования функции set()
, а пустые множества могут создаваться
только с помощью функции set()
– их нельзя создать с помощью пары
пустых скобок. Множество, состоящее из одного или более элементов,
может быть создано с помощью последовательности элементов, разделенных
запятыми, заключенной в фигурные скобки. Другой способ создания
множеств заключается в использовании генераторов множеств. Множества
всегда содержат уникальные элементы – добавление повторяющихся
элементов возможно, но не имеет смысла. Например, следующие три
множества являются эквивалентными: set("apple")
, set("aple")
и
{'e', 'p', 'a', 'l'}
. Благодаря этой их особенности множества часто
используются для устранения повторяющихся значений. Например, если
предположить, что x
– это список строк, то после выполнения
инструкции x = list(set(x))
в списке останутся только уникальные
строки, причем располагаться они могут в произвольном порядке.
Рисунок 4: Стандартные операторы множеств
Множества поддерживают встроенную функцию len()
и быструю проверку
на вхождение с помощью операторов in
и not in
. Они также предоставляют
типичный набор операторов, как показано на рис. .
Полный перечень методов и операторов, применимых к множествам,
приводится в табл. collections:sets:tbl:1. Все методы семейства
«update» (set.update()
, set.intersection_update()
и т. д.) могут принимать в качестве
аргумента любые итерируемые объекты, но эквивалентные им
комбинированные операторы присваивания (|=
, &=
и т. д.) требуют, чтобы
оба операнда были множествами.
Таблица 2. Методы и операторы множеств
Синтаксис | Описание |
s.add(x) | Добавляет элементы x во множество s , если они отсутствуют в s |
s.clear() | Удаляет все элементы из множества s |
s.difference(t) или s-t | Возвращает новое множество включающее элементы множества s , которые отсутствуют в множестве t |
s.difference_update(t) или s-=t | Удаляет из множества s все элементы, присутствующие в множестве t |
s.discard(x) | Удаляет элемент x из множества s , если он присутствует в множестве s |
s.intersection(t) или s & t | Возвращает новое множество, включающее элементы, присутствующие одновременно в множествах s и t |
s.intersection_update(t) или s &= t | Оставляет во множестве s пересечение множеств s и t |
s.isdisjoint(t) | Возвращает True , если множества s и t не имеют общих элементов |
s.issubset(t) или s <= t | Возвращает True , если множество s эквивалентно множеству t или является его подмножеством; чтобы проверить, является ли множество s только подмножеством множества t , следует использовать проверку s < t |
s.issuperset(t) или s >= t | Возвращает True , если множество s эквивалентно множеству t или является его надмножеством; чтобы проверить, является ли множество s только надмножеством множества t , следует использовать проверку s > t |
s.pop() | Возвращает и удаляет случайный элемент множества s или возбуждает исключение KeyError , если s – это пустое множество |
s.remove(x) | Удаляет элемент x из множества s или возбуждает исключение KeyError , если элемент x отсутствует в множестве s |
s.symmetric_difference(t) или s ^ t | Возвращает новое множество, включающее все элементы, присутствующие в множествах s и t , за исключением элементов, присутствующих в обоих множествах одновременно |
s.symmetric_difference_update(t) или s ^= t | Возвращает в множестве s результат строгой дизъюнкции множеств s и t |
s.union(t) или s | t | Возвращает новое множество, включающее все элементы множества s и все элементы множества t , отсутствующие в множестве s |
s.update(t) или s |= t | Добавляет во множество s все элементы множества t , отсутствующие в множестве s |
В дополнение к возможности создавать множества с помощью функции
set()
или литералов, существует возможность создавать множества с
помощью генераторов множеств. Генератор множества – это выражение и
цикл с необязательным условием, заключенные в фигурные скобки. Подобно
генераторам списков, генераторы множеств поддерживают две формы
записи:
{expression for item in iterable}
{expression for item in iterable if condition}
Мы могли бы использовать генераторы множеств для фильтрации нежелательных элементов (когда порядок следования элементов не имеет значения), как показано ниже:
html = {x for x in files if x.lower().endswith((".htm", ".html"))}
Если предположить, что files
– это список имен файлов, то данный
генератор множества создает множество html
, в котором хранятся
только имена файлов с расширениями .htm
и .html
, независимо от
регистра символов.
Как и в случае с генераторами списков, в генераторах множеств используются итерируемые объеты, которые в свою очередь могут быть генераторами множеств (или генераторами любого другого типа), что позволяет создавать весьма замысловатые генераторы множеств.
frozenset
Фиксированное множество (frozenset
) – это множество, которое после
создания невозможно изменить. Хотя при этом мы, конечно, можем
повторно связать переменную, которая ссылалась на фиксированное
множество, с чем-то другим. Фиксированные множества могут создаваться
только в результате обращения к имени типа frozenset
как к
функции. При вызове frozenset()
без аргументов возвращается пустое
фиксированное множество; с аргументом типа frozenset
возвращается
поверхностная копия аргумента; если аргумент имеет другой тип,
выполняется попытка преобразовать его в объект типа frozenset
. Эта
функция принимает не более одного аргумента.
Поскольку фиксированные множества относятся к категории неизменяемых объектов, они поддерживают только те методы и операторы, которые воспроизводят результат, не оказывая воздействия на фиксированное множество или на множества, к которым они применяются.
Поскольку фиксированные множества относятся к категории неизменяемых
объектов, они поддерживают только те методы и операторы, которые
воспроизводят результат, не оказывая воздействия на фиксированное
множество или на множества, к которым они применяются.
В табл. collections:sets:tbl:1 перечислены все методы множеств из
которых фиксированными множествами поддерживаются: frozenset.copy()
,
frozenset.difference()
(-
), frozenset.intersection()
(&
),
frozenset.isdis-joint()
, frozenset.issubset()
(<=
и <
для
выявления подмножеств), frozenset.issuperset()
(>=
и >
для
выявления надмножеств), frozenset.union()
(|
) и
frozenset.symmetric_difference()
(^
).
Если двухместный оператор применяется ко множеству и фиксированному
множеству, тип результата будет совпадать с типом операнда, стоящего
слева от оператора. То есть если предположить, что f
– это
фиксированное множество, а s
– это обычное множество, то выражение
f & s
вернет объект типа frozenset, а выражение s & f
– объект
типа set
. В случае операторов ==
и !=
порядок операндов не имеет
значения, и выражение f == s
вернет True
, только если оба
множества содержат одни и те же элементы.
Другое следствие неизменности фиксированных множеств заключается в том, что они соответствуют критерию хеширования, предъявляемому к элементам множеств, и потому множества и фиксированные множества могут содержать другие фиксированные множества.