Комплетан водич са примерима кода

U ovom uputstvu, istražićemo osnove skupova u programskom jeziku Python, kao i raznovrsne metode koje se mogu primeniti za manipulaciju i izmenu ovih skupova.

Skupovi su integralni deo Python-ovih ugrađenih struktura podataka. Kada se suočite sa potrebom za rad sa kolekcijom jedinstvenih elemenata, skupovi postaju idealna struktura za pristup i obradu podataka.

U narednim odeljcima, detaljno ćemo analizirati osnove Python skupova, uključujući različite metode za njihovu upotrebu. Takođe, naučićemo kako se izvode standardne operacije sa skupovima u Python-u.

Započnimo!

Osnove Python skupova

U Python-u, skup je definisan kao neuređena kolekcija elemenata bez ponavljanja. To podrazumeva da svi elementi unutar skupa moraju biti različiti.

Elementi se mogu dodavati i uklanjati iz skupa, što znači da je skup promenljiva kolekcija. Može sadržati elemente različitih tipova podataka, ali svaki pojedinačni element u skupu mora biti hešabilan.

U Python-u, za objekat se kaže da je hešabilan ako se njegova heš vrednost nikada ne menja. Većina nepromenljivih objekata, poput Python stringova, torki i rečnika, su hešabilni.

Detaljnije ćemo se posvetiti kreiranju skupova. Za sada, razmotrimo sledeća dva primera:

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'

Prvi skup sadrži tri broja, torku i string. Inicijalizacija je uspešna bez greške. Nasuprot tome, drugi skup sadrži listu umesto torke. Lista je promenljiva kolekcija i ne može se heširati, pa inicijalizacija generiše grešku TypeError.

📑 Da sumiramo, možemo definisati Python skup kao promenljivu kolekciju jedinstvenih, hešabilnih elemenata.

Kako kreirati Python skup

Počećemo sa objašnjenjem kako se kreira skup u Python-u.

#1. Korišćenje eksplicitne inicijalizacije

Skup u Python-u se može kreirati navođenjem elemenata, odvojenih zarezima (,), i zatvorenih u par vitičastih zagrada {}.

py_set1 = {'Python','C','C++','JavaScript'}
type(py_set1)

# Output
set

Ako ste prethodno radili sa Python listama, znate da [] inicijalizuje praznu listu. Iako je Python skup omeđen vitičastim zagradama {}, ne možete koristiti par {} za inicijalizaciju skupa. Razlog je taj što {} inicijalizuje Python rečnik, a ne skup.

py_set2 = {}
type(py_set2)

# Output
dict

Ponovnim pozivanjem funkcije type() možete proveriti da li je py_set2 rečnik (dict).

#2. Korišćenje funkcije set()

Ako želite da inicijalizujete prazan skup i naknadno mu dodajete elemente, to možete uraditi pomoću funkcije set().

py_set3 = set()
type(py_set3)

# Output
set

#3. Konvertovanje drugih iterabilnih objekata u skup

Drugi način kreiranja skupova je konvertovanjem drugih iterabilnih objekata, kao što su liste i torke, u skupove pomoću funkcije set(iterabilni_objekat).

py_list = ['Python','C','C++','JavaScript','C']
py_set4 = set(py_list)
print(py_set4)
# {'C++', 'C', 'JavaScript', 'Python'} # ponavljajući element 'C' je uklonjen
type(py_set4)
# set

U gornjem primeru, py_list sadrži ‘C’ dva puta. Međutim, u py_set4, ‘C’ se pojavljuje samo jednom, jer skup predstavlja kolekciju jedinstvenih elemenata. Ova tehnika konverzije u skup se često koristi za uklanjanje duplikata iz Python lista.

Kako dodati elemente u Python skup

Počećemo kreiranjem praznog skupa py_set i koristićemo ga tokom ovog uputstva.

py_set = set()
len(py_set) # vraća dužinu skupa
# Output
0

#1. Korišćenje metode .add()

Za dodavanje elemenata u skup, može se koristiti metoda .add(). Sintaksa set.add(element) dodaje element u skup.

Radi ilustracije, dodavaćemo elemente u Python skup i ispisivati skup na svakom koraku.

▶ Dodajmo string ‘Python’ kao element u py_set.

py_set.add('Python')
print(py_set)

# Output
{'Python'}

Zatim, dodajmo još jedan element.

py_set.add('C++')
print(py_set)

# Output
{'Python', 'C++'}

Važno je napomenuti da metoda .add() dodaje element u skup samo ako on već ne postoji. Ako skup već sadrži element koji želite dodati, operacija dodavanja neće imati efekta.

Da bismo ovo potvrdili, pokušajmo da dodamo ‘C++’ u py_set ponovo.

py_set.add('C++')
print(py_set)

# Output
{'Python', 'C++'}

Skup već sadrži ‘C++’, tako da operacija dodavanja nema efekta.

▶ Dodajmo još nekoliko elemenata u skup.

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. Korišćenje metode .update()

Do sada smo videli kako se dodaju elementi u postojeći skup – jedan po jedan element.

Šta ako želite da dodate više elemenata odjednom?

To možete učiniti pomoću metode .update() sa sintaksom: set.update(kolekcija) za dodavanje elemenata iz kolekcije u skup. Kolekcija može biti lista, torka, rečnik, itd.

py_set.update(['Julia','Ruby','Scala','Java'])
print(py_set)

# Output
{'C', 'C++', 'Java', 'JavaScript', 'Julia', 'Python', 'Ruby', 'Rust', 'Scala'}

Ova metoda je korisna kada želite da dodate kolekciju elemenata u skup, bez potrebe za kreiranjem drugog objekta u memoriji.

U sledećem odeljku ćemo naučiti kako ukloniti elemente iz skupa.

Kako ukloniti elemente iz Python skupa

Razmotrimo sledeći skup (py_set pre operacije update()).

py_set = {'C++', 'JavaScript', 'Python', 'Rust', 'C'}

#1. Korišćenje metode .pop()

set.pop() nasumično uklanja element iz skupa i vraća ga. Pozovimo metodu pop na py_set i vidimo šta vraća.

py_set.pop()

# Output
'Rust'

Ovog puta, poziv metode .pop() je vratio string ‘Rust’.

Napomena: Pošto metoda .pop() vraća element nasumično, moguće je da ćete dobiti drugi element kada pokrenete kod.

Kada pregledamo skup, ‘Rust’ više nije prisutan u skupu.

print(py_set)

# Output
{'JavaScript', 'Python', 'C++', 'C'}

#2. Korišćenje metoda .remove() i .discard()

U praksi, možda ćete želeti da uklonite određene elemente iz skupa. Za to se mogu koristiti metode .remove() i .discard().

set.remove(element) uklanja element iz skupa.

py_set.remove('C')
print(py_set)

# Output
{'JavaScript', 'Python', 'C++'}

Ako pokušamo da uklonimo element koji ne postoji u skupu, dobićemo 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'

Pogledajmo ponovo py_set. Sada ima tri elementa.

print(py_set)

# Output
{'JavaScript', 'Python', 'C++'}

Sa sintaksom set.discard(element), metoda .discard() takođe uklanja elemente iz skupa.

py_set.discard('C++')
print(py_set)

# Output
{'JavaScript', 'Python'}

Međutim, razlikuje se od metode .remove() po tome što ne generiše KeyError kada pokušamo da uklonimo element koji ne postoji.

Ako pokušamo da uklonimo ‘Scala’ (koja ne postoji) sa liste pomoću metode .discard(), nećemo dobiti grešku.

py_set.discard('Scala') #bez greške!
print(py_set)

# Output
{'JavaScript', 'Python'}

Kako pristupiti elementima Python skupa

Do sada smo naučili kako se dodaju i uklanjaju elementi iz Python skupova. Međutim, još nismo videli kako se pristupa pojedinačnim elementima unutar skupa.

Pošto je skup neuređena kolekcija, on se ne može indeksirati. Stoga, ako pokušate da pristupite elementima skupa pomoću indeksa, dobićete grešku, kao što je prikazano.

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

Dakle, kako pristupiti elementima u skupu?

Postoje dva uobičajena načina:

  • Prolazak kroz skup i pristup svakom elementu
  • Provera da li je određeni element član skupa

▶ Prođimo kroz skup i pristupimo elementima pomoću for petlje.

for elt in py_set:
  print(elt)

# Output
C++
JavaScript
Python
Rust
C

U praksi, možda ćete želeti da proverite da li je dati element prisutan u skupu pomoću `in` operatora.

Napomena: `element in skup` vraća True ako je element prisutan u skupu; inače, vraća False.

U ovom primeru, py_set sadrži ‘C++’ i ne sadrži ‘Julia’, pa `in` operator vraća True i False, respektivno.

'C++' in py_set
# True
'Julia' in py_set
# False

Kako pronaći dužinu Python skupa

Kao što smo ranije videli, možete koristiti funkciju `len()` da biste dobili broj elemenata prisutnih u skupu.

py_set = {'C++', 'JavaScript', 'Python', 'Rust', 'C'}
len(py_set)

# Output: 5

Kako obrisati Python skup

Za brisanje skupa, odnosno uklanjanje svih elemenata iz njega, možete koristiti metodu .clear().

Pozovimo metodu .clear() na py_set.

py_set.clear()

Ako pokušate da ga ispišete, dobićete `set()` – što ukazuje da je skup prazan. Takođe možete pozvati funkciju `len()` da biste proverili da li je dužina skupa nula.

print(py_set)
# set()
print(len(py_set))
# 0

Do sada smo naučili kako da izvršavamo osnovne CRUD operacije nad Python skupovima:

  • Kreiranje: Korišćenje funkcije `set()`, konverzije tipa i inicijalizacije
  • Čitanje: Pristup elementima skupa pomoću petlji i `in` operatora za proveru članstva
  • Ažuriranje: Dodavanje, uklanjanje elemenata iz skupova i ažuriranje skupova
  • Brisanje: Brisanje skupa uklanjanjem svih elemenata iz njega

Uobičajene operacije sa skupovima, objašnjene Python kodom

Python skupovi nam takođe omogućavaju da izvršavamo osnovne operacije sa skupovima. U ovom odeljku ćemo ih analizirati.

#1. Unija skupova u Python-u

U teoriji skupova, unija dva skupa je skup svih elemenata koji se nalaze u barem jednom od ta dva skupa. Ako postoje dva skupa, A i B, unija sadrži elemente koji su prisutni samo u A, samo u B, kao i one koji su prisutni i u A i u B.

Za pronalaženje unije skupova, možete koristiti `|` operator ili metodu .union() sa sintaksom: skupA.union(skupB).

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}

Unija skupova je komutativna operacija; dakle, A U B je isto što i B U A. Proverimo to zamenom pozicija setA i setB u pozivu metode .union().

setB.union(setA)

# Output
{1, 2, 3, 4, 5, 6, 7, 8, 9}

#2. Presek skupova u Python-u

Druga česta operacija sa skupovima je presek dva skupa, A i B. Operacija preseka skupova vraća skup koji sadrži sve elemente koji su prisutni i u A i u B.

Za izračunavanje preseka, možete koristiti `&` operator ili metodu .intersection(), kao što je objašnjeno u sledećem isječku koda.

print(setA & setB)

# Output
{9}

setA.intersection(setB)

# Output
{9}

U ovom primeru, element 9 je prisutan i u skupu A i u skupu B; stoga, skup preseka sadrži samo ovaj element.

Slično kao i unija skupova, presek skupova je takođe komutativna operacija.

setB.intersection(setA)

# Output
{9}

#3. Razlika skupova u Python-u

Za bilo koja dva skupa, unija i presek nam pomažu da pronađemo elemente koji su prisutni u oba skupa, odnosno u barem jednom skupu. S druge strane, razlika skupova nam pomaže da pronađemo elemente koji su prisutni u jednom skupu, ali ne i u drugom.

– setA.difference(setB) daje skup elemenata koji su prisutni samo u skupu A, a ne u skupu B.

– setB.difference(setA) daje skup elemenata koji su prisutni samo u skupu B, a ne u skupu A.

print(setA - setB)

print(setB - setA)

# Output
{1, 3, 5, 7}
{8, 2, 4, 6}

Očigledno je da A – B nije isto što i B – A, tako da razlika skupova nije komutativna operacija.

setA.difference(setB)
# {1, 3, 5, 7}

setB.difference(setA)
# {2, 4, 6, 8}

#4. Simetrična razlika skupova u Python-u

Dok nam presek skupova daje elemente koji su prisutni u oba skupa, simetrična razlika skupova vraća skup elemenata koji su prisutni u tačno jednom od skupova.

Razmotrite sledeći primer.

setA = {1,3,5,7,10,12}
setB = {2,4,6,8,10,12}

Za izračunavanje skupa simetričnih razlika, možete koristiti ^ operator ili metodu .symmetric_difference().

print(setA ^ setB)

# Output
{1, 2, 3, 4, 5, 6, 7, 8}

Elementi 10 i 12 su prisutni i u skupu A i u skupu B. Stoga, oni nisu prisutni u skupu simetričnih razlika.

setA.symmetric_difference(setB)

# Output
{1, 2, 3, 4, 5, 6, 7, 8}

Pošto operacija simetrične razlike skupova prikuplja sve elemente koji se pojavljuju u tačno jednom od dva skupa, rezultujući skup je isti, bez obzira na redosled kojim su elementi prikupljeni. Dakle, simetrična razlika skupova je komutativna operacija.

setB.symmetric_difference(setA)

# Output
{1, 2, 3, 4, 5, 6, 7, 8}

#5. Podskupovi i nadskupovi u Python-u

U teoriji skupova, podskupovi i nadskupovi pomažu u razumevanju odnosa između dva skupa.

Za dva data skupa A i B, skup B je podskup skupa A ako su svi elementi u skupu B takođe prisutni u skupu A. Skup A je nadskup skupa B.

Razmotrimo primer dva skupa: languages i languages_extended.

languages = {'Python', 'JavaScript','C','C++'}
languages_extended = {'Python', 'JavaScript','C','C++','Rust','Go','Scala'}

U Python-u, možete koristiti metodu .issubset() da proverite da li je dati skup podskup drugog skupa.

setA.issubset(setB) vraća True ako je setA podskup skupa B; u suprotnom, vraća False.

U ovom primeru, languages je podskup languages_extended.

languages.issubset(languages_extended)
# Output
True

Slično tome, možete koristiti metodu .issuperset() da proverite da li je dati skup nadskup drugog skupa.

setA.issuperset(setB) vraća True ako je setA nadskup skupa B; u suprotnom, vraća False.

languages_extended.issuperset(languages)
# Output
True

Pošto je languages_extended nadskup skupa languages, languages_extended.issuperset(languages) vraća True, kao što se vidi iznad.

Zaključak

Nadam se da vam je ovo uputstvo pomoglo da razumete kako funkcionišu Python skupovi, metode skupova za CRUD operacije i uobičajene operacije nad skupovima. Kao sledeći korak, možete pokušati da ih koristite u svojim Python projektima.

Možete pogledati i druge detaljne Python vodiče. Srećno u učenju!