Синтаксис
empty_set = set() # инициализирует пустое множество
literal_set = {'foo', 'bar', 'baz'} # строит множество с 3мя строками внутри
set_from_list = set(['foo', 'bar', 'baz']) # вызов функции set() для создания нового множества
set_from_iter = set(x for x in range(30)) # используются произвольные итерации для создания нового множества
set_from_iter = {x for x in [random.randint(0,10) for i in range(10)]} # альтернативная нотация
Замечания
Множества не упорядочены и имеют очень быстрое время поиска (приблизительно O(1)). Они отлично подходят для использования, когда у вас есть коллекция вещей, порядок которых не имеет значения, и вам необходим поиск по имени много раз. Если нужен поиск по индексу, то лучше рассмотреть списки для использования. Если важна упорядоченность, то также лучше рассмотреть списки.
Множества изменяемы и поэтому не могут быть хэшированы, поэтому вы не можете их использовать в качестве ключей словаря или помещать их в другие наборы или где-либо еще, где требуются хэшированые типы. В таких случаях вы может использовать неизменяемое множество frozenset
. Элементы множества должны быть способны к хэшированию. Это значит, что они должны иметь корректный метод __hash__
, который совместим с __eq__
. В общем, изменяемые типы такие как list
или set
не способны к хэшированию и не могут быть помещены во множество. Если вы столкнулись с этой проблемой, рассмотрите использование dict
и неизменяемые ключи.
Получить уникальные элементы списка
Допустим, у вас есть список ресторанов - может быть, вы читаете его из файла. Вы заботитесь об уникальных ресторанах в списке. Лучший способ получить уникальные элементы из списка - превратить его во множество:
restaurants = ["McDonald's", "Burger King", "McDonald's", "Chicken Chicken"]
unique_restaurants = set(restaurants)
print(unique_restaurants)
>>>Out: {'Burger King', "McDonald's", 'Chicken Chicken'}
Обратите внимание, что набор не в том же порядке, что и исходный список; это потому , что множества являются неупорядоченными, так же , как dict
.
Это может быть легко преобразован обратно в List
с Python встроенный в list
функций, что дает еще один список , который тот же список , как оригинал , но без дубликатов:
list(unique_restaurants)
>>>Out: ['Burger King', "McDonald's", 'Chicken Chicken']
Также принято видеть это одной строкой:
# удалены все дубликаты и возвращается другой список
list(set(restaurants))
Теперь любые операции, которые могут быть выполнены в исходном списке, могут быть выполнены снова.
Операции на множествах
с другими наборами
# Пересечения множеств
{1, 2, 3, 4, 5}.intersection({3, 4, 5, 6})
>>>Out: {3, 4, 5}
{1, 2, 3, 4, 5} & {3, 4, 5, 6}
>>>Out: {3, 4, 5}
# Объединение множеств
{1, 2, 3, 4, 5}.union({3, 4, 5, 6})
>>>Out: {1, 2, 3, 4, 5, 6}
{1, 2, 3, 4, 5} | {3, 4, 5, 6}
>>>Out: {1, 2, 3, 4, 5, 6}
# Разница множеств
{1, 2, 3, 4}.difference({2, 3, 5})
>>>Out: {1, 4}
{1, 2, 3, 4} - {2, 3, 5}
>>>Out: {1, 4}
# Симметрическая разность множеств
{1, 2, 3, 4}.symmetric_difference({2, 3, 5})
>>>Out: {1, 4, 5}
{1, 2, 3, 4} ^ {2, 3, 5}
>>>Out: {1, 4, 5}
# проверка суперпозиции множеств
{1, 2}.issuperset({1, 2, 3})
>>>Out: False
{1, 2} >= {1, 2, 3}
>>>Out: False
# проверка подмножества
{1, 2}.issubset({1, 2, 3})
>>>Out: True
{1, 2} <= {1, 2, 3}
>>>Out: True
# проверка непересечения
{1, 2}.isdisjoint({3, 4})
>>>Out: True
{1, 2}.isdisjoint({1, 4})
>>>Out: False
с отдельными элементами
# проверка наличия элемента в множестве
2 in {1,2,3}
>>>Out: True
4 in {1,2,3}
>>>Out: False
4 not in {1,2,3}
>>>Out: True
# Доблавение и удаление из множества
s = {1,2,3}
s.add(4)
s == {1,2,3,4}
>>>Out: True
s.discard(3)
s == {1,2,4}
>>>Out: True
s.discard(5) #элемента 5 нет, поэтому если его не учитывать ничего не произойдет
s == {1,2,4}
>>>Out: True
s.remove(2)
s == {1,4}
>>>Out: True
s.remove(2) #нельзя удалить элемент 2, т.к. его уже нет в множестве
>>>Out: KeyError: 2 #
Операции множества возвращают новые множества, но имеют соответствующие комбинированные операторы присваивания:
Метод | Операция на месте | метод на месте |
---|---|---|
объединение | s|= t | update |
пересечение | s &= t | intersection_update |
разница | s -= t | difference_update |
симметрическая разница | s ^ = t | symmetric_difference_update |
Например:
s = {1, 2}
s.update({3, 4})
s == {1, 2, 3, 4}
>>>Out: True
Множество множеств
{{1,2}, {3,4}} #приводит к ошибке
>>>Out: TypeError: unhashable type: 'set'
Вместо этого используйте frozenset
:
{frozenset({1, 2}), frozenset({3, 4})}
Операции над множествами с использованием методов и встроенных функций
Определим два множества a
и b
a = {1, 2, 2, 3, 4}
b = {3, 3, 4, 4, 5}
a.intersection(b)
>>>Out: {3, 4}
объединение
a.union(b)
возвращает новый набор с элементами, присутствующими в любом a
и b
a.union(b)
>>>Out: {1, 2, 3, 4, 5}
разница
a.difference(b)
возвращает новый набор с элементами , присутствующими в , но не в a
b
a.difference(b)
>>>Out: {1, 2}
b.difference(a)
>>>Out: {5}
Симметричная разница
a.symmetric_difference(b)
возвращает новый набор с элементами, присутствующими в любом a
или b
, но не в обоих множествах
a.symmetric_difference(b)
>>>Out: {1, 2, 5}
b.symmetric_difference(a)
>>>Out: {1, 2, 5}
Примечание: a.symmetric_difference(b) == b.symmetric_difference(a)
Подмножество и суперсет
c.issubset(a)
проверяет, соответствует ли каждый элемент c
в a
a.issuperset(c)
проверяет, является ли каждый элемент c
находится d a
.
c = {1, 2}
c.issubset(a)
>>>Out: True
a.issuperset(c)
>>>Out: True
Последние операции имеют эквивалентные операторы, как показано ниже:
Метод | Оператор |
---|---|
a.intersection(b) | a & b |
a.union(b) | a | b |
a.difference(b) | a - b |
a.symmetric_difference(b) | a ^ b |
a.issubset(b) | a <= b |
a.issuperset(b) | a >= b |
Несвязные множества
Множества a
и d
не пересекаются, если ни один элемент a
не находится также в d
, и наоборот.
d = {5, 6}
a.isdisjoint(b) # {2, 3, 4} are in both sets
>>>Out: False
a.isdisjoint(d)
>>>Out: True
# это эквивалентная проверка, но менее эффективная
len(a & d) == 0
>>>Out: True
# еще менее эффективная
a & d == set()
>>>Out: True
Тестирование членства
Встроенный ключевое слово in
ищет вхождения
1 in a
>>>Out: True
6 in a
>>>Out: False
длина
Встроенная функция len()
возвращает количество элементов в множестве
len(a)
>>>Out: 4
len(b)
>>>Out: 3
Множества против мультимножеств
Множества - это неупорядоченные коллекции отдельных элементов. Но иногда мы хотим работать с неупорядоченными коллекциями элементов, которые не обязательно различны и отслеживают множественность элементов.
Рассмотрим этот пример:
setA = {'a','b','b','c'}
setA
>>>Out: set(['a', 'c', 'b'])
При сохранении строки 'a'
, 'b'
, 'b'
, 'c'
в структуру набора данных , мы потеряли информацию о том , что 'b'
встречается дважды. Конечно, сохранение элементов в списке сохранит эту информацию.
listA = ['a','b','b','c']
listA
>>>Out: ['a', 'b', 'b', 'c']
но структура данных списка вводит дополнительный ненужный порядок, который замедляет наши вычисления.
from collections import Counter
counterA = Counter(['a','b','b','c'])
counterA
>>>Out: Counter({'b': 2, 'a': 1, 'c': 1})
Counter
представляет собой словарь, где элементы хранятся в виде ключей словаря и их счетчики хранятся в виде значений словаря. И, как и все словари, это неупорядоченная коллекция.