Документация по Python

Множества (sets) в Python

В: Документация по Python

Синтаксис

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 представляет собой словарь, где элементы хранятся в виде ключей словаря и их счетчики хранятся в виде значений словаря. И, как и все словари, это неупорядоченная коллекция.

Еще от кодкамп
Замечательно! Вы успешно подписались.
Добро пожаловать обратно! Вы успешно вошли
Вы успешно подписались на кодкамп.
Срок действия вашей ссылки истек.
Ура! Проверьте свою электронную почту на наличие волшебной ссылки для входа.
Успех! Ваша платежная информация обновлена.
Ваша платежная информация не была обновлена.