Operacje na zbiorach (np. określanie unii zbiorów, zbiorów iloczynu i podzbiorów) za pomocą typu zbioru Pythona

Biznes

Python udostępnia wbudowany typ danych set, który obsługuje zbiory.

Typ set jest zbiorem nieduplikowanych elementów (elementów, które nie mają tej samej wartości, elementów unikatowych) i może wykonywać operacje na zbiorach, takie jak union set, product set i difference set.

W tym rozdziale wyjaśnione są podstawowe operacje na zbiorach typu set wraz z przykładowym kodem.

  • Tworzenie obiektów zestawu: {},set()
  • notacja włączania zbiorów
  • Liczba elementów w zbiorze:len()
  • Dodawanie elementu do zbioru:add()
  • Usuń element ze zbioru: discard(),remove(),pop(),clear()
  • Wasset (połączenie, unia):|operator,union()
  • Zestawy wyrobów (części wspólne, skrzyżowania, przecięcia):& operator,intersection()
  • dopełnienie względne:-operator,difference()
  • zestaw różnic symetrii:^ operator,symmetric_difference()
  • podzbiór lub nie:<= operator,issubset()
  • Górny zestaw czy nie:>= operator,issuperset()
  • Określenie, czy są one wzajemnie pierwszorzędne, czy też nie:isdisjoint()

Typ set jest typem mutowalnym, który może dodawać i usuwać elementy. Istnieje również typ frozenset, który ma taką samą operację set i inne metody jak typ set, ale jest niezmienny (nie może być modyfikowany przez dodawanie, usuwanie lub inne modyfikacje elementów).

Utworzenie obiektu zestawu:: {}, set()

Generowane przez nawiasy falowe {}

Obiekty typu set można tworzyć, zamykając elementy w nawiasach klamrowych {}.

Jeśli występują zduplikowane wartości, są one ignorowane, a jako elementy pozostają tylko wartości unikatowe.

s = {1, 2, 2, 3, 1, 4}

print(s)
print(type(s))
# {1, 2, 3, 4}
# <class 'set'>

Elementami mogą być różne typy. Nie można jednak rejestrować obiektów aktualizowalnych, takich jak typy list. Dozwolone są tuple.

Ponadto, ponieważ typy zestawów są nieuporządkowane, kolejność ich generowania nie jest zachowywana.

s = {1.23, 'abc', (0, 1, 2), 'abc'}

print(s)
# {(0, 1, 2), 1.23, 'abc'}

# s = {[0, 1, 2]}
# TypeError: unhashable type: 'list'

Różne typy, takie jak int i float, są uważane za duplikaty, jeśli ich wartości są równoważne.

s = {100, 100.0}

print(s)
# {100}

Ponieważ pusty nawias klamrowy {} jest uważany za typ słownikowy, obiekt typu pusty zbiór (empty set) można utworzyć za pomocą opisanego dalej konstruktora.

s = {}

print(s)
print(type(s))
# {}
# <class 'dict'>

Generowane przez konstruktor set()

Obiekty typu set można również tworzyć za pomocą konstruktora set().

Podanie jako argumentu obiektu iterowalnego, takiego jak lista lub tuple, powoduje wygenerowanie obiektu zbioru, którego elementami są wyłącznie wartości unikatowe, z wykluczeniem elementów zduplikowanych.

l = [1, 2, 2, 3, 1, 4]

print(l)
print(type(l))
# [1, 2, 2, 3, 1, 4]
# <class 'list'>

s_l = set(l)

print(s_l)
print(type(s_l))
# {1, 2, 3, 4}
# <class 'set'>

Niemutowalne typy frozenset są tworzone za pomocą konstruktora frozenset().

fs_l = frozenset(l)

print(fs_l)
print(type(fs_l))
# frozenset({1, 2, 3, 4})
# <class 'frozenset'>

Jeśli argument zostanie pominięty, zostanie utworzony pusty obiekt typu set (pusty zbiór).

s = set()

print(s)
print(type(s))
# set()
# <class 'set'>

Duplikaty można usunąć z listy lub tupli za pomocą funkcji set(), ale kolejność oryginalnej listy nie jest zachowana.

Aby zamienić typ zestawu na listę lub tuple, użyj funkcji list(),tuple().

l = [2, 2, 3, 1, 3, 4]

l_unique = list(set(l))
print(l_unique)
# [1, 2, 3, 4]

Informacje o usuwaniu zduplikowanych elementów z zachowaniem kolejności, wyodrębnianiu tylko zduplikowanych elementów oraz przetwarzaniu zduplikowanych elementów w tablicy dwuwymiarowej (liście list) można znaleźć w poniższym artykule.

notacja włączania zbiorów

Oprócz rozumienia list istnieją również rozumienia zbiorów. W przypadku list comprehensions wystarczy zastąpić nawiasy kwadratowe [] nawiasami klamrowymi {}.

s = {i**2 for i in range(5)}

print(s)
# {0, 1, 4, 9, 16}

Więcej informacji na temat notacji list comprehension można znaleźć w poniższym artykule.

Liczba elementów w zbiorze: len()

Liczbę elementów w zbiorze można uzyskać za pomocą wbudowanej funkcji len().

s = {1, 2, 2, 3, 1, 4}

print(s)
print(len(s))
# {1, 2, 3, 4}
# 4

Aby policzyć liczbę elementów na każdej liście, na której znajdują się elementy z duplikatami wartości itp.

Dodawanie elementu do zbioru: add()

Aby dodać element do zbioru, należy użyć metody add().

s = {0, 1, 2}

s.add(3)
print(s)
# {0, 1, 2, 3}

Usuń element ze zbioru: discard(),remove(),pop(),clear()

Aby usunąć element ze zbioru, należy użyć metod discard(), remove(), pop() i clear().

Metoda discard() usuwa element podany w argumencie. Jeśli podano wartość, która nie istnieje w zbiorze, nic nie jest robione.

s = {0, 1, 2}

s.discard(1)
print(s)
# {0, 2}

s = {0, 1, 2}

s.discard(10)
print(s)
# {0, 1, 2}

Metoda remove() również usuwa element określony w argumencie, ale zwracany jest błąd KeyError, jeśli podano wartość, która nie istnieje w zbiorze.

s = {0, 1, 2}

s.remove(1)
print(s)
# {0, 2}

# s = {0, 1, 2}

# s.remove(10)
# KeyError: 10

Metoda pop() usuwa elementy ze zbioru i zwraca ich wartości. Nie można wybrać, które wartości mają zostać usunięte. Pusty zbiór spowoduje wystąpienie błędu KeyError.

s = {2, 1, 0}

v = s.pop()

print(s)
print(v)
# {1, 2}
# 0

s = {2, 1, 0}

print(s.pop())
# 0

print(s.pop())
# 1

print(s.pop())
# 2

# print(s.pop())
# KeyError: 'pop from an empty set'

Metoda clear() usuwa wszystkie elementy i czyni zbiór pustym.

s = {0, 1, 2}

s.clear()
print(s)
# set()

Wasset (połączenie, unia): |operator, union()

Zbiór unii (połączenie, union) można uzyskać za pomocą operatora | lub metody union().

s1 = {0, 1, 2}
s2 = {1, 2, 3}
s3 = {2, 3, 4}

s_union = s1 | s2
print(s_union)
# {0, 1, 2, 3}

s_union = s1.union(s2)
print(s_union)
# {0, 1, 2, 3}

Dla danej metody można określić wiele argumentów. Oprócz typu set jako argumenty można podawać listy i tuple, które można przekonwertować na typ set za pomocą funkcji set(). To samo dotyczy kolejnych operatorów i metod.

s_union = s1.union(s2, s3)
print(s_union)
# {0, 1, 2, 3, 4}

s_union = s1.union(s2, [5, 6, 5, 7, 5])
print(s_union)
# {0, 1, 2, 3, 5, 6, 7}

Zestawy wyrobów (części wspólne, skrzyżowania, przecięcia): & operator, intersection()

Zbiór iloczynów (część wspólna, przecięcie i przecięcie) można uzyskać za pomocą operatora & lub metody intersection().

s_intersection = s1 & s2
print(s_intersection)
# {1, 2}

s_intersection = s1.intersection(s2)
print(s_intersection)
# {1, 2}

s_intersection = s1.intersection(s2, s3)
print(s_intersection)
# {2}

dopełnienie względne: -operator, difference()

Zbiór różnic można uzyskać za pomocą operatora – lub metody difference().

s_difference = s1 - s2
print(s_difference)
# {0}

s_difference = s1.difference(s2)
print(s_difference)
# {0}

s_difference = s1.difference(s2, s3)
print(s_difference)
# {0}

zestaw różnic symetrii: ^ operator, symmetric_difference()

Zbiór różnicy symetrycznej (zbiór elementów zawartych tylko w jednym z dwóch) można uzyskać za pomocą operatora ^ lub funkcji symmetric_difference().

Równoważne dysjunkcji wyłącznej (XOR) w operacjach logicznych.

s_symmetric_difference = s1 ^ s2
print(s_symmetric_difference)
# {0, 3}

s_symmetric_difference = s1.symmetric_difference(s2)
print(s_symmetric_difference)
# {0, 3}

podzbiór lub nie: <= operator, issubset()

Aby określić, czy dany zbiór jest podzbiorem innego zbioru, należy użyć operatora <= lub metody issubset().

s1 = {0, 1}
s2 = {0, 1, 2, 3}

print(s1 <= s2)
# True

print(s1.issubset(s2))
# True

Zarówno operator <=, jak i metoda issubset() zwracają wartość true dla zbiorów równoważnych.

Aby określić, czy jest to podzbiór prawdziwy, należy użyć operatora <=, który dla zbiorów równoważnych zwraca wartość false.

print(s1 <= s1)
# True

print(s1.issubset(s1))
# True

print(s1 < s1)
# False

Górny zestaw czy nie: >= operator, issuperset()

Aby określić, czy jeden zbiór jest supersetem innego, należy użyć operatora >= lub funkcji issuperset().

s1 = {0, 1}
s2 = {0, 1, 2, 3}

print(s2 >= s1)
# True

print(s2.issuperset(s1))
# True

Zarówno operator >=, jak i metoda issuperset() zwracają wartość true dla zbiorów równoważnych.

Aby określić, czy jest to prawdziwy superzbiór, należy użyć operatora >=, który zwraca fałsz w przypadku zbiorów równoważnych.

print(s1 >= s1)
# True

print(s1.issuperset(s1))
# True

print(s1 > s1)
# False

Określenie, czy są one wzajemnie pierwszorzędne, czy też nie: isdisjoint()

Aby określić, czy dwa zbiory są względem siebie pierwsze, należy użyć metody isdisjoint().

s1 = {0, 1}
s2 = {1, 2}
s3 = {2, 3}

print(s1.isdisjoint(s2))
# False

print(s1.isdisjoint(s3))
# True