W tym przewodniku zapoznasz się z fundamentalnymi aspektami zbiorów w Pythonie oraz z różnymi metodami, które pozwalają na ich modyfikację.
Zbiory stanowią jedną z wbudowanych struktur danych w Pythonie. Są idealne, gdy potrzebujesz pracować z kolekcją unikalnych elementów.
W kolejnych sekcjach omówimy podstawowe zasady działania zbiorów Pythona oraz metody, które umożliwią efektywną pracę z nimi. Następnie przejdziemy do typowych operacji na zbiorach, które można wykonywać w Pythonie.
Zacznijmy!
Podstawowe informacje o zbiorach w Pythonie
W Pythonie zbiór to nieuporządkowana kolekcja, w której każdy element jest unikalny. Innymi słowy, w zbiorze nie mogą występować duplikaty.
Zbiory są strukturami zmiennymi, co oznacza, że można dodawać do nich elementy i je z nich usuwać. Mogą przechowywać elementy różnych typów danych. Istotne jest jednak, aby każdy element w zbiorze był haszowalny.
Obiekt w Pythonie uznaje się za haszowalny, jeśli jego wartość hash nie ulega zmianie w czasie. Większość obiektów niezmiennych, takich jak ciągi znaków, krotki i słowniki, jest haszowalna.
Szczegółowo omówimy proces tworzenia zbiorów. Na razie spójrzmy na poniższe dwa przykłady:
py_set = {0,1,2,(2,3,4),'Cool!'} py_set = {0,1,2,[2,3,4],'Oops!'} # Output --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-40-2d3716c7fe01> in <module>() ----> 1 py_set = {0,1,2,[2,3,4],'Oops!'} TypeError: unhashable type: 'list'
Pierwszy zbiór składa się z trzech liczb, krotki i ciągu znaków. Inicjalizacja tego zbioru przebiega bezproblemowo. Natomiast drugi zbiór zawiera listę zamiast krotki. Lista jest kolekcją zmienną, a więc nie można jej haszować, co powoduje błąd TypeError podczas inicjalizacji.
📑 Podsumowując, zbiór Pythona można zdefiniować jako zmienną kolekcję unikalnych i haszowalnych elementów.
Jak utworzyć zbiór w Pythonie?
Zaczniemy od poznania różnych sposobów tworzenia zbiorów w Pythonie.
#1. Użycie jawnej inicjalizacji
Zbiór w Pythonie można utworzyć, definiując jego elementy, oddzielone przecinkami i umieszczone w nawiasach klamrowych {}.
py_set1 = {'Python','C','C++','JavaScript'} type(py_set1) # Output set
Osoby zaznajomione z listami w Pythonie wiedzą, że [] inicjuje pustą listę. Mimo że zbiory są umieszczane w nawiasach klamrowych {}, nie można ich zainicjować za pomocą pustych nawiasów {}. Dzieje się tak, ponieważ {} inicjuje słownik, a nie zbiór.
py_set2 = {} type(py_set2) # Output dict
Możesz użyć funkcji type(), aby upewnić się, że `py_set2` jest słownikiem (dict).
#2. Użycie funkcji set()
Jeśli chcesz utworzyć pusty zbiór, a później dodać do niego elementy, możesz użyć funkcji `set()`.
py_set3 = set() type(py_set3) # Output set
#3. Konwersja innych struktur iterowalnych do zbioru
Inną metodą tworzenia zbiorów jest przekształcenie innych struktur iterowalnych, takich jak listy i krotki, w zbiory za pomocą funkcji `set(iterable)`.
py_list = ['Python','C','C++','JavaScript','C'] py_set4 = set(py_list) print(py_set4) # {'C++', 'C', 'JavaScript', 'Python'} # repeating element 'C' removed type(py_set4) # set
W powyższym przykładzie 'C’ pojawia się dwa razy w `py_list`. Natomiast w zbiorze `py_set4` 'C’ występuje tylko raz, ponieważ zbiór zawiera wyłącznie unikalne elementy. Metoda konwersji do zbioru jest często wykorzystywana do usuwania duplikatów z list w Pythonie.
Jak dodawać elementy do zbioru w Pythonie?
Zacznijmy od utworzenia pustego zbioru o nazwie `py_set` i będziemy go używać w dalszej części tego przewodnika.
py_set = set() len(py_set) # returns the length of a set # Output 0
#1. Użycie metody .add()
Aby dodać elementy do zbioru, możesz skorzystać z metody `.add()`. Składnia `set.add(element)` dodaje `element` do zbioru.
Dla przejrzystości, dodamy elementy do zbioru i będziemy go wyświetlać po każdym kroku.
▶️ Dodajmy ciąg znaków 'Python’ jako element do `py_set`.
py_set.add('Python') print(py_set) # Output {'Python'}
Następnie dodajmy kolejny element.
py_set.add('C++') print(py_set) # Output {'Python', 'C++'}
Należy pamiętać, że metoda `.add()` dodaje element do zbioru tylko wtedy, gdy nie występuje w nim. Jeżeli element, który próbujesz dodać, już znajduje się w zbiorze, operacja dodawania nie będzie miała żadnego efektu.
Aby to sprawdzić, spróbujmy dodać 'C++’ do `py_set`.
py_set.add('C++') print(py_set) # Output {'Python', 'C++'}
Zbiór zawiera już 'C++’, więc operacja dodawania jest ignorowana.
▶️ Dodajmy do zbioru kilka kolejnych elementów.
py_set.add('C') print(py_set) py_set.add('JavaScript') print(py_set) py_set.add('Rust') print(py_set) # Output {'Python', 'C++', 'C'} {'JavaScript', 'Python', 'C++', 'C'} {'Rust', 'JavaScript', 'Python', 'C++', 'C'}
#2. Użycie metody .update()
Do tej pory poznaliśmy metodę dodawania pojedynczych elementów do zbioru.
Co zrobić, jeśli chcesz dodać do zbioru sekwencję elementów?
Możesz użyć metody `.update()` o składni: `set.update(kolekcja)`, aby dodać elementy z kolekcji do zbioru. Kolekcją może być lista, krotka, słownik itd.
py_set.update(['Julia','Ruby','Scala','Java']) print(py_set) # Output {'C', 'C++', 'Java', 'JavaScript', 'Julia', 'Python', 'Ruby', 'Rust', 'Scala'}
Metoda ta jest przydatna, gdy chcesz dodać kolekcję elementów do zbioru bez tworzenia nowego obiektu w pamięci.
W kolejnej sekcji nauczymy się, jak usuwać elementy ze zbioru.
Jak usuwać elementy ze zbioru w Pythonie?
Rozważmy zbiór `py_set` w stanie sprzed operacji aktualizacji.
py_set = {'C++', 'JavaScript', 'Python', 'Rust', 'C'}
#1. Użycie metody .pop()
`set.pop()` losowo usuwa element ze zbioru i zwraca go. Wywołajmy metodę `pop` na `py_set` i zobaczmy, co zostanie zwrócone.
py_set.pop() # Output 'Rust'
Tym razem wywołanie metody `.pop()` zwróciło 'Rust’.
Uwaga: ponieważ metoda `.pop()` zwraca element losowy, wynik może być inny przy ponownym uruchomieniu kodu.
Sprawdzając zawartość zbioru, można zauważyć, że 'Rust’ już w nim nie występuje.
print(py_set) # Output {'JavaScript', 'Python', 'C++', 'C'}
#2. Użycie metod .remove() i .discard()
Często zachodzi potrzeba usunięcia konkretnego elementu ze zbioru. W tym celu możesz wykorzystać metody `.remove()` i `.discard()`.
`set.remove(element)` usuwa `element` ze zbioru.
py_set.remove('C') print(py_set) # Output {'JavaScript', 'Python', 'C++'}
Próba usunięcia elementu, który nie występuje w zbiorze, spowoduje błąd `KeyError`.
py_set.remove('Scala') # Output --------------------------------------------------------------------------- KeyError Traceback (most recent call last) <ipython-input-58-a1abab3a8892> in <module>() ----> 1 py_set.remove('Scala') KeyError: 'Scala'
Sprawdźmy jeszcze raz, co zawiera `py_set`. Aktualnie mamy w nim trzy elementy.
print(py_set) # Output {'JavaScript', 'Python', 'C++'}
Metoda `.discard(element)` również usuwa elementy ze zbioru.
py_set.discard('C++') print(py_set) # Output {'JavaScript', 'Python'}
Różnica między metodami `.remove()` i `.discard()` polega na tym, że `.discard()` nie zgłasza błędu `KeyError` w przypadku próby usunięcia elementu, który nie znajduje się w zbiorze.
Jeśli spróbujemy usunąć 'Scala’ (która nie występuje) za pomocą metody `.discard()`, błąd nie zostanie zgłoszony.
py_set.discard('Scala') #no error! print(py_set) # Output {'JavaScript', 'Python'}
Jak uzyskać dostęp do elementów zbioru w Pythonie?
Dotychczas nauczyliśmy się, jak dodawać i usuwać elementy ze zbiorów. Jednak nie wiemy jeszcze, jak uzyskać dostęp do poszczególnych elementów w zbiorze.
Ponieważ zbiór jest strukturą nieuporządkowaną, nie można do niej odwoływać się za pomocą indeksów. Próba dostępu do elementów zbioru za pomocą indeksu spowoduje błąd, jak pokazano poniżej.
py_set = {'C++', 'JavaScript', 'Python', 'Rust', 'C'} print(py_set[0]) # Output --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-27-0329274f4580> in <module>() ----> 1 print(py_set[0]) TypeError: 'set' object is not subscriptable
Jak więc uzyskać dostęp do elementów w zbiorze?
Można to zrobić na dwa sposoby:
- Iteracja po zbiorze i dostęp do każdego elementu
- Sprawdzenie, czy element należy do zbioru
▶️ Iteracja po zbiorze i dostęp do elementów za pomocą pętli `for`.
for elt in py_set: print(elt) # Output C++ JavaScript Python Rust C
Często chcemy sprawdzić, czy dany element występuje w zbiorze, za pomocą operatora `in`.
Uwaga: operator `in` zwraca `True`, jeżeli element znajduje się w zbiorze, a `False` w przeciwnym wypadku.
W tym przykładzie `py_set` zawiera 'C++’ i nie zawiera 'Julia’, więc operator `in` zwróci odpowiednio `True` i `False`.
'C++' in py_set # True 'Julia' in py_set # False
Jak sprawdzić rozmiar zbioru w Pythonie?
Jak już wcześniej pokazano, funkcja `len()` pozwala uzyskać liczbę elementów w zbiorze.
py_set = {'C++', 'JavaScript', 'Python', 'Rust', 'C'} len(py_set) # Output: 5
Jak wyczyścić zbiór w Pythonie?
Aby wyczyścić zbiór, usuwając z niego wszystkie elementy, możesz użyć metody `.clear()`.
Wywołajmy metodę `.clear()` na `py_set`.
py_set.clear()
Jeśli spróbujesz wyświetlić zbiór, otrzymasz `set()`, co oznacza, że zbiór jest pusty. Możesz również użyć funkcji `len()`, aby sprawdzić, czy jego długość wynosi zero.
print(py_set) # set() print(len(py_set)) # 0
Dotychczas omówiliśmy podstawowe operacje CRUD na zbiorach Pythona:
- Tworzenie: przy użyciu funkcji `set()`, konwersji typu i inicjalizacji.
- Odczyt: dostęp do elementów zbioru za pomocą pętli oraz operatora `in` do sprawdzania obecności elementów.
- Aktualizacja: dodawanie, usuwanie elementów ze zbiorów i aktualizacja zbiorów.
- Usuwanie: wyczyszczenie zbioru poprzez usunięcie wszystkich elementów.
Typowe operacje na zbiorach, wyjaśnione na przykładzie kodu Pythona
Zbiory w Pythonie umożliwiają również wykonywanie podstawowych operacji, które są znane z teorii mnogości. Omówimy je w tej sekcji.
#1. Suma zbiorów w Pythonie
W teorii mnogości suma dwóch zbiorów to zbiór, który zawiera wszystkie elementy z obu zbiorów. Jeśli mamy dwa zbiory A i B, suma zawiera elementy, które występują tylko w A, tylko w B, oraz elementy, które występują zarówno w A, jak i w B.
Aby znaleźć sumę zbiorów, można użyć operatora `|` lub metody `.union()` o składni: `setA.union(setB)`.
setA = {1,3,5,7,9} setB = {2,4,6,8,9} print(setA | setB) # Output {1, 2, 3, 4, 5, 6, 7, 8, 9} setA.union(setB) # Output {1, 2, 3, 4, 5, 6, 7, 8, 9}
Suma zbiorów jest operacją przemienną, więc AUB jest tym samym co BUA. Sprawdźmy to, zamieniając miejscami `setA` i `setB` w wywołaniu metody `.union()`.
setB.union(setA) # Output {1, 2, 3, 4, 5, 6, 7, 8, 9}
#2. Iloczyn zbiorów w Pythonie
Inną częstą operacją na zbiorach jest iloczyn dwóch zbiorów A i B. Iloczyn zbiorów zwraca zbiór zawierający wszystkie elementy, które występują zarówno w A, jak i w B.
Aby obliczyć iloczyn, możesz użyć operatora `&` lub metody `.intersection()`, jak wyjaśniono w poniższym przykładzie.
print(setA & setB) # Output {9} setA.intersection(setB) # Output {9}
W tym przykładzie element 9 jest obecny zarówno w `setA`, jak i w `setB`. Zatem iloczyn zbiorów zawiera tylko ten element.
Podobnie jak suma zbiorów, iloczyn zbiorów jest operacją przemienną.
setB.intersection(setA) # Output {9}
#3. Różnica zbiorów w Pythonie
Mając dwa zbiory, suma i iloczyn pomagają nam znaleźć elementy występujące w obu lub co najmniej jednym ze zbiorów. Z kolei różnica zbiorów pozwala na znalezienie elementów, które występują w jednym zbiorze, ale nie występują w drugim.
– `setA.difference(setB)` zwraca zbiór elementów, które występują tylko w `setA`, a nie w `setB`.
– `setB.difference(setA)` zwraca zbiór elementów, które występują tylko w `setB`, a nie w `setA`.
print(setA - setB) print(setB - setA) # Output {1, 3, 5, 7} {8, 2, 4, 6}
Oczywiście AB nie jest tym samym co BA, więc różnica zbiorów nie jest operacją przemienną.
setA.difference(setB) # {1, 3, 5, 7} setB.difference(setA) # {2, 4, 6, 8}
#4. Różnica symetryczna zbiorów w Pythonie
Podczas gdy iloczyn zbiorów zwraca elementy występujące w obu zbiorach, różnica symetryczna zbiorów zwraca zbiór elementów, które występują tylko w jednym z dwóch zbiorów.
Rozważmy poniższy przykład.
setA = {1,3,5,7,10,12} setB = {2,4,6,8,10,12}
Aby obliczyć różnicę symetryczną, możesz użyć operatora `^` lub metody `.symmetric_difference()`.
print(setA ^ setB) # Output {1, 2, 3, 4, 5, 6, 7, 8}
Elementy 10 i 12 występują zarówno w `setA`, jak i w `setB`, więc nie są zawarte w różnicy symetrycznej.
setA.symmetric_difference(setB) # Output {1, 2, 3, 4, 5, 6, 7, 8}
Ponieważ operacja różnicy symetrycznej zbiera wszystkie elementy, które występują dokładnie w jednym z dwóch zbiorów, wynikowy zbiór jest taki sam niezależnie od kolejności zbiorów. Dlatego różnica symetryczna zbiorów jest operacją przemienną.
setB.symmetric_difference(setA) # Output {1, 2, 3, 4, 5, 6, 7, 8}
#5. Podzbiory i nadzbiory w Pythonie
W teorii mnogości podzbiory i nadzbiory pomagają określić relację między dwoma zbiorami.
Mając dwa zbiory A i B, zbiór B jest podzbiorem zbioru A, jeśli wszystkie elementy zbioru B występują również w zbiorze A. Zbiór A jest wtedy nadzbiorem zbioru B.
Rozważmy przykład dwóch zbiorów: `languages` i `languages_extended`.
languages = {'Python', 'JavaScript','C','C++'} languages_extended = {'Python', 'JavaScript','C','C++','Rust','Go','Scala'}
W Pythonie możesz użyć metody `.issubset()`, aby sprawdzić, czy dany zbiór jest podzbiorem innego zbioru.
`setA.issubset(setB)` zwraca `True`, jeśli `setA` jest podzbiorem `setB`; w przeciwnym razie zwraca `False`.
W tym przykładzie `languages` jest podzbiorem `languages_extended`.
languages.issubset(languages_extended) # Output True
Podobnie, możesz użyć metody `.issuperset()`, aby sprawdzić, czy dany zbiór jest nadzbiorem innego zbioru.
`setA.issuperset(setB)` zwraca `True`, jeśli `setA` jest nadzbiorem `setB`; w przeciwnym razie zwraca `False`.
languages_extended.issuperset(languages) # Output True
Ponieważ `languages_extended` jest nadzbiorem `languages`, `languages_extended.issuperset(languages)` zwraca `True`, jak pokazano powyżej.
Podsumowanie
Mam nadzieję, że ten przewodnik pomógł ci zrozumieć działanie zbiorów w Pythonie, metody zbiorów służące do operacji CRUD i typowe operacje na zbiorach. Kolejnym krokiem może być próba ich użycia w projektach w Pythonie.
Zachęcam do zapoznania się z innymi naszymi przewodnikami po Pythonie. Powodzenia w nauce!
newsblog.pl