Historia pytania:
Zbiory (set) zostały wprowadzone w Pythonie jako osobny wbudowany typ od wersji 2.4 (wcześniej były realizowane jako zewnętrzny moduł). Umożliwiają efektywne przechowywanie unikalnych, nieuporządkowanych elementów i wspierają wiele standardowych operacji teorii zbiorów: sumę, przecięcie, różnicę, różnicę symetryczną i sprawdzanie podzbiorów.
Problem:
Bez set trzeba używać list, co prowadzi do nieefektywnego wyszukiwania unikalnych elementów, co spowalnia algorytmy, które używają dużej liczby sprawdzeń przynależności. Set jest realizowany poprzez tablicę haszującą, dlatego wszystkie operacje wyszukiwania, dodawania i usuwania są wykonywane w amortyzowanym czasie O(1). Jednak ta struktura może powodować nieoczekiwane problemy — na przykład utratę kolejności elementów, ograniczenia na typy elementów (muszą być niemodyfikowalne i haszowalne) oraz niezrozumienie cech porównania zbiorów i ich interakcji z innymi strukturami.
Rozwiązanie:
Używaj set, gdy potrzebujesz przechowywać tylko unikalne elementy i wykonywać na nich operacje teorii zbiorów. Należy pamiętać, że elementy muszą być haszowalne (na przykład liczby, ciągi, tuple, ale nie listy i nie dict). Do pracy z set dostępny jest bogaty zestaw wbudowanych metod (add, remove, union, intersection, difference, issubset, itp.).
Przykład kodu:
s1 = {1, 2, 3, 4} s2 = {3, 4, 5} print(s1 | s2) # {1, 2, 3, 4, 5} (suma) print(s1 & s2) # {3, 4} (przecięcie) print(s1 - s2) # {1, 2} (różnica) print(3 in s1) # True (sprawdzenie przynależności)
Kluczowe cechy:
Czy można dodawać typy zmienne (na przykład listy) do set?
Nie, elementy zbioru muszą być haszowalne i niemodyfikowalne. List lub dict nie można dodać do set, Python zgłosi TypeError.
s = set() s.add([1, 2, 3]) # TypeError: unhashable type: 'list'
Czy set zachowuje kolejność elementów?
Nie. Od momentu utworzenia set elementy nie są gwarantowane do zwracania w kolejności, w jakiej zostały dodane, szczególnie przy zmianie rozmiaru zbioru.
s = {5, 2, 8, 1} print(s) # Kolejność nieokreślona
Czym różni się set od frozenset i czy można używać frozenset jako elementu set?
frozenset to niemodyfikowalna wersja set. Można go używać jako element innego set lub jako klucz dict, ponieważ jest haszowalny.
fs = frozenset([1, 2, 3]) s = set() s.add(fs) # OK
Programista chciał przechowywać unikalne elementy i wybrał set, nie uwzględniając kolejności ich pojawiania się. W rezultacie część logiki biznesowej, która zależała od kolejności przetwarzania, przestała działać.
Zalety:
Wady:
W zadaniu szybkiej filtracji unikalnych rekordów z dużego zbioru wybrano set, ponieważ istotny był jedynie fakt unikalności, a nie kolejność. Wydajność znacznie wzrosła, kod się uprościł.
Zalety:
Wady: