sets.md
1> **Источник:** https://python-all.ru/2.7/library/sets.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 8.7. [`sets`](https://python-all.ru/2.7/library/sets.html#module-sets) – Неупорядоченные коллекции уникальных элементов89Новое в версии 2.3.1011Устарело с версии 2.6: Встроенные типы [`set`](https://python-all.ru/2.7/library/stdtypes.html#set)/[`frozenset`](https://python-all.ru/2.7/library/stdtypes.html#frozenset) заменяют этот модуль.1213Модуль [`sets`](https://python-all.ru/2.7/library/sets.html#module-sets) предоставляет классы для создания и работы с неупорядоченными коллекциями уникальных элементов. Обычно используется для проверки принадлежности, удаления дубликатов из последовательности и выполнения стандартных математических операций над множествами, таких как пересечение, объединение, разность и симметрическая разность.1415Как и другие коллекции, множества поддерживают `x in set`, `len(set)` и `for x in set`. Будучи неупорядоченной коллекцией, множество не запоминает положение элементов или порядок вставки. Поэтому множества не поддерживают индексацию, срезы и другое поведение, свойственное последовательностям.1617Большинство приложений, работающих с множествами, используют класс [`Set`](https://python-all.ru/2.7/library/sets.html#sets.Set), который предоставляет все методы множества, кроме [`__hash__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__hash__). Для более сложных приложений, требующих хеш-функцию, класс [`ImmutableSet`](https://python-all.ru/2.7/library/sets.html#sets.ImmutableSet) добавляет метод [`__hash__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__hash__), но опускает методы, изменяющие содержимое множества. Оба класса [`Set`](https://python-all.ru/2.7/library/sets.html#sets.Set) и [`ImmutableSet`](https://python-all.ru/2.7/library/sets.html#sets.ImmutableSet) являются производными от `BaseSet`, абстрактного класса, полезного для определения, является ли объект множеством: `isinstance(obj, BaseSet)`.1819Классы множеств реализованы с использованием словарей. Соответственно, требования к элементам множеств такие же, как к ключам словарей: а именно, элемент должен определять как [`__eq__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__eq__), так и [`__hash__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__hash__). В результате множества не могут содержать изменяемые элементы, такие как списки или словари. Однако они могут содержать неизменяемые коллекции, например кортежи или экземпляры [`ImmutableSet`](https://python-all.ru/2.7/library/sets.html#sets.ImmutableSet). Для удобства реализации множеств из множеств внутренние множества автоматически преобразуются в неизменяемую форму, например, `Set([Set(['dog'])])` преобразуется в `Set([ImmutableSet(['dog'])])`.2021#### `class sets.Set([iterable])`2223Создаёт новый пустой объект [`Set`](https://python-all.ru/2.7/library/sets.html#sets.Set). Если указан необязательный параметр *iterable*, обновляет множество элементами, полученными при итерации. Все элементы в *iterable* должны быть неизменяемыми или преобразуемыми в неизменяемые с помощью протокола, описанного в разделе [Протокол автоматического преобразования в неизменяемые](https://python-all.ru/2.7/library/sets.html#immutable-transforms).2425#### `class sets.ImmutableSet([iterable])`2627Создаёт новый пустой объект [`ImmutableSet`](https://python-all.ru/2.7/library/sets.html#sets.ImmutableSet). Если указан необязательный параметр *iterable*, обновляет множество элементами, полученными при итерации. Все элементы в *iterable* должны быть неизменяемыми или преобразуемыми в неизменяемые с помощью протокола, описанного в разделе [Протокол автоматического преобразования в неизменяемые](https://python-all.ru/2.7/library/sets.html#immutable-transforms).2829Поскольку объекты [`ImmutableSet`](https://python-all.ru/2.7/library/sets.html#sets.ImmutableSet) предоставляют метод [`__hash__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__hash__), они могут использоваться как элементы множества или как ключи словаря. Объекты [`ImmutableSet`](https://python-all.ru/2.7/library/sets.html#sets.ImmutableSet) не имеют методов для добавления или удаления элементов, поэтому все элементы должны быть известны на момент вызова конструктора.3031## 8.7.1. Объекты множеств3233Экземпляры [`Set`](https://python-all.ru/2.7/library/sets.html#sets.Set) и [`ImmutableSet`](https://python-all.ru/2.7/library/sets.html#sets.ImmutableSet) предоставляют следующие операции:3435| Операция | Эквивалентно | Результат |36| --- | --- | --- |37| `len(s)` | | количество элементов в множестве *s* (мощность) |38| `x in s` | | проверить принадлежность *x* множеству *s* |39| `x not in s` | | проверить, что *x* не принадлежит множеству *s* |40| `s.issubset(t)` | `s <= t` | проверить, что каждый элемент *s* принадлежит *t* |41| `s.issuperset(t)` | `s >= t` | проверить, что каждый элемент *t* принадлежит *s* |42| `s.union(t)` | `s \| t` | новое множество с элементами из обоих *s* и *t* |43| `s.intersection(t)` | `s & t` | новое множество с элементами, общими для *s* и *t* |44| `s.difference(t)` | `s - t` | новое множество с элементами из *s*, не входящими в *t* |45| `s.symmetric_difference(t)` | `s ^ t` | новое множество с элементами, входящими либо в *s*, либо в *t*, но не в оба |46| `s.copy()` | | новое множество с поверхностной копией *s* |4748Обратите внимание: неоператорные версии `union()`, `intersection()`, `difference()` и `symmetric_difference()` принимают любой итерируемый объект в качестве аргумента. В отличие от них, операторные аналоги требуют, чтобы их аргументы были множествами. Это исключает подверженные ошибкам конструкции вроде `Set('abc') & 'cbs'` в пользу более читаемых `Set('abc').intersection('cbs')`.4950Изменено в версии 2.3.1: Ранее все аргументы должны были быть множествами.5152Кроме того, оба типа [`Set`](https://python-all.ru/2.7/library/sets.html#sets.Set) и [`ImmutableSet`](https://python-all.ru/2.7/library/sets.html#sets.ImmutableSet) поддерживают сравнение множеств. Два множества равны тогда и только тогда, когда каждый элемент одного множества содержится в другом (каждое является подмножеством другого). Множество меньше другого множества тогда и только тогда, когда первое множество является строгим подмножеством второго (является подмножеством, но не равным). Множество больше другого множества тогда и только тогда, когда первое множество является строгим надмножеством второго (является надмножеством, но не равным).5354Сравнения на подмножество и равенство не обобщаются до функции полного упорядочения. Например, любые два непересекающихся множества не равны и не являются подмножествами друг друга, поэтому *все* следующие выражения возвращают `False`: `a<b`, `a==b`, или `a>b`. Соответственно, множества не реализуют метод [`__cmp__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__cmp__).5556Поскольку множества определяют лишь частичное упорядочение (отношения подмножеств), результат метода `list.sort()` для списков множеств не определён.5758В следующей таблице перечислены операции, доступные в [`ImmutableSet`](https://python-all.ru/2.7/library/sets.html#sets.ImmutableSet), но отсутствующие в [`Set`](https://python-all.ru/2.7/library/sets.html#sets.Set):5960| Операция | Результат |61| --- | --- |62| `hash(s)` | возвращает хеш-значение для *s* |6364В следующей таблице перечислены операции, доступные в [`Set`](https://python-all.ru/2.7/library/sets.html#sets.Set), но отсутствующие в [`ImmutableSet`](https://python-all.ru/2.7/library/sets.html#sets.ImmutableSet):6566| Операция | Эквивалентно | Результат |67| --- | --- | --- |68| `s.update(t)` | *s* \|= *t* | возвращает множество *s* с элементами, добавленными из *t* |69| `s.intersection_update(t)` | *s* &= *t* | возвращает множество *s*, сохраняя только eлементы, также найденные в *t* |70| `s.difference_update(t)` | *s* -= *t* | возвращает множество *s* после удаления eлементов, найденных в *t* |71| `s.symmetric_difference_update(t)` | *s* ^= *t* | возвращает множество *s* с элементами из *s* или *t*, но не из обоих |72| `s.add(x)` | | добавляет элемент *x* в множество *s* |73| `s.remove(x)` | | удаляет *x* из множества *s*; вызывает [`KeyError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.KeyError), если отсутствует |74| `s.discard(x)` | | удаляет *x* из множества *s*, если присутствует |75| `s.pop()` | | удаляет и возвращает произвольный element из *s*; вызывает [`KeyError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.KeyError), если пусто |76| `s.clear()` | | удаляет все элементы из множества *s* |7778Примечание: неоператорные версии `update()`, `intersection_update()`, `difference_update()` и `symmetric_difference_update()` принимают любой итерируемый объект в качестве аргумента.7980Изменено в версии 2.3.1: Ранее все аргументы должны были быть множествами.8182Также обратите внимание: модуль также включает метод `union_update()`, который является псевдонимом для `update()`. Этот метод включён для обратной совместимости. Программистам следует предпочитать метод `update()`, поскольку он поддерживается встроенными типами [`set()`](https://python-all.ru/2.7/library/stdtypes.html#set) и [`frozenset()`](https://python-all.ru/2.7/library/stdtypes.html#frozenset).8384## 8.7.2. Пример8586```python87>>> from sets import Set88>>> engineers = Set(['John', 'Jane', 'Jack', 'Janice'])89>>> programmers = Set(['Jack', 'Sam', 'Susan', 'Janice'])90>>> managers = Set(['Jane', 'Jack', 'Susan', 'Zack'])91>>> employees = engineers | programmers | managers # объединение92>>> engineering_management = engineers & managers # пересечение93>>> fulltime_management = managers - engineers - programmers # разность94>>> engineers.add('Marvin') # добавляет элемент95>>> print engineers 96Set(['Jane', 'Marvin', 'Janice', 'John', 'Jack'])97>>> employees.issuperset(engineers) # проверка надмножества98False99>>> employees.update(engineers) # обновление из другого множества100>>> employees.issuperset(engineers)101True102>>> for group in [engineers, programmers, managers, employees]: 103... group.discard('Susan') # безусловное удаление элемента104... print group105...106Set(['Jane', 'Marvin', 'Janice', 'John', 'Jack'])107Set(['Janice', 'Jack', 'Sam'])108Set(['Jane', 'Zack', 'Jack'])109Set(['Jack', 'Sam', 'Jane', 'Marvin', 'Janice', 'John', 'Zack'])110```111112## 8.7.3. Протокол автоматического преобразования в неизменяемый тип113114Множества могут содержать только неизменяемые элементы. Для удобства изменяемые объекты [`Set`](https://python-all.ru/2.7/library/sets.html#sets.Set) автоматически копируются в [`ImmutableSet`](https://python-all.ru/2.7/library/sets.html#sets.ImmutableSet) перед добавлением в качестве элемента множества.115116Механизм заключается в том, чтобы всегда добавлять [хэшируемый](https://python-all.ru/2.7/glossary.html#term-hashable) элемент, или, если он не хэшируемый, элемент проверяется на наличие метода `__as_immutable__()`, который возвращает неизменяемый эквивалент.117118Поскольку объекты [`Set`](https://python-all.ru/2.7/library/sets.html#sets.Set) имеют метод `__as_immutable__()`, возвращающий экземпляр [`ImmutableSet`](https://python-all.ru/2.7/library/sets.html#sets.ImmutableSet), можно создавать множества множеств.119120Похожий механизм нужен методам [`__contains__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__contains__) и `remove()`, которым требуется хэшировать элемент для проверки членства в множестве. Эти методы проверяют элемент на хэшируемость и, если она отсутствует, ищут метод `__as_temporarily_immutable__()`, который возвращает элемент, обёрнутый классом, предоставляющим временные методы для [`__hash__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__hash__), [`__eq__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__eq__), и [`__ne__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__ne__).121122Альтернативный механизм избавляет от необходимости создавать отдельную копию исходного изменяемого объекта.123124Объекты [`Set`](https://python-all.ru/2.7/library/sets.html#sets.Set) реализуют метод `__as_temporarily_immutable__()`, который возвращает объект [`Set`](https://python-all.ru/2.7/library/sets.html#sets.Set), обёрнутый новым классом `_TemporarilyImmutableSet`.125126Два механизма добавления хэшируемости обычно невидимы для пользователя; однако может возникнуть конфликт в многопоточной среде, где один поток обновляет множество, а другой временно обернул его в `_TemporarilyImmutableSet`. Другими словами, множества изменяемых множеств не являются потокобезопасными.127128## 8.7.4. Сравнение со встроенными типами [`set`](https://python-all.ru/2.7/library/stdtypes.html#set)129130Встроенные типы [`set`](https://python-all.ru/2.7/library/stdtypes.html#set) и [`frozenset`](https://python-all.ru/2.7/library/stdtypes.html#frozenset) были разработаны на основе уроков, извлечённых из модуля [`sets`](https://python-all.ru/2.7/library/sets.html#module-sets). Ключевые отличия:131132- [`Set`](https://python-all.ru/2.7/library/sets.html#sets.Set) и [`ImmutableSet`](https://python-all.ru/2.7/library/sets.html#sets.ImmutableSet) были переименованы в [`set`](https://python-all.ru/2.7/library/stdtypes.html#set) и [`frozenset`](https://python-all.ru/2.7/library/stdtypes.html#frozenset).133- Нет эквивалента для `BaseSet`. Вместо этого используйте `isinstance(x, (set, frozenset))`.134- Алгоритм хэширования для встроенных типов работает значительно лучше (меньше коллизий) для большинства наборов данных.135- Встроенные версии создают более компактные pickle-объекты.136- Встроенные версии не имеют метода `union_update()`. Вместо этого используйте метод `update()`, который является эквивалентным.137- Встроенные версии не имеют метода `_repr(sorted=True)`. Вместо этого используйте встроенные функции [`repr()`](https://python-all.ru/2.7/library/functions.html#repr) и [`sorted()`](https://python-all.ru/2.7/library/functions.html#sorted): `repr(sorted(s))`.138- Встроенная версия не имеет протокола автоматического преобразования в неизменяемый тип. Многие находили эту функцию сбивающей с толку, и никто в сообществе не сообщал о её реальном применении.139