Množina (typ set) je skupina hodnôt bez opakovania a bez poradia – presne ako množina v matematike. Hodí sa vždy, keď nás zaujíma, či niečo v skupine je, a nie koľkokrát alebo na ktorom mieste: rôzne písmená v texte, unikátni návštevníci, spoločné prvky dvoch zoznamov. Zisťovanie, či je hodnota v množine, je navyše veľmi rýchle.
Čo sa naučíš
- vytvoriť množinu a pridávať či odoberať prvky,
- zistiť príslušnosť prvku operátorom
in, - počítať zjednotenie, prienik a rozdiel množín,
- použiť množinu na odstránenie duplikátov a porovnávanie skupín.
1Vytvorenie množiny
Množinu zapíšeme do zložených zátvoriek. Opakujúce sa hodnoty sa uložia iba raz:
>>> farby = {"červená", "modrá", "červená", "zelená"} >>> len(farby) 3 >>> cisla = {3, 1, 3, 2, 1} >>> cisla {1, 2, 3}
Z iných postupností vytvorí množinu funkcia set. To je najjednoduchší spôsob, ako sa zbaviť duplikátov:
>>> set([1, 2, 2, 3, 3, 3]) {1, 2, 3} >>> len(set("abrakadabra")) 5 >>> sorted(set("abrakadabra")) ['a', 'b', 'd', 'k', 'r']
1.1Množina nemá poradie
Prvky množiny nemajú pevné poradie ani indexy. Pri výpise sa môžu zobraziť v inom poradí, než v akom sme ich zapísali – a na inom počítači aj v inom poradí ako tu. Ak potrebuješ poradie, použi sorted(mnozina), ktorá vráti zoradený zoznam.
>>> m = {"jablko", "hruška", "slivka"} >>> sorted(m) ['hruška', 'jablko', 'slivka'] >>> m[0] TypeError: 'set' object is not subscriptable
1.2Čo môže byť v množine
Prvkami množiny môžu byť iba nemenné hodnoty: čísla, reťazce, n-tice. Zoznam do množiny vložiť nemožno:
>>> {(1, 2), (3, 4)} {(1, 2), (3, 4)} >>> {[1, 2]} TypeError: unhashable type: 'list'
2Pridávanie a odoberanie
| Metóda | Čo urobí |
|---|---|
m.add(x) | pridá prvok x (ak už tam je, nič sa nestane) |
m.remove(x) | odstráni x; ak tam nie je, chyba KeyError |
m.discard(x) | odstráni x, ak tam je; inak nič |
m.clear() | vyprázdni množinu |
Výstup:
3 rôzni návštevníci: ['Ema', 'Ján', 'Sofia']
['Ema', 'Sofia']3Príslušnosť: in
Operátor in (a not in) zistí, či prvok v množine je:
Výstup:
oaoaiePri zozname musí Python pri in prechádzať prvky jeden po druhom. Množina si prvky ukladá tak, že odpoveď nájde takmer okamžite bez ohľadu na veľkosť. Ak sa v programe veľakrát pýtaš, či je niečo v skupine, ulož skupinu do množiny. O rýchlosti programov viac v téme Algoritmické úlohy.
4Množinové operácie
Množinové operácie poznáš z matematiky. V Pythone sa zapisujú operátormi (alebo metódami s rovnakým významom):
| Operácia | Operátor | Metóda | Výsledok obsahuje prvky, ktoré sú… |
|---|---|---|---|
| zjednotenie | a | b | a.union(b) | aspoň v jednej z množín |
| prienik | a & b | a.intersection(b) | v oboch množinách |
| rozdiel | a - b | a.difference(b) | v a, ale nie v b |
| symetrický rozdiel | a ^ b | a.symmetric_difference(b) | práve v jednej z nich |
>>> a = {1, 2, 3, 4} >>> b = {3, 4, 5, 6} >>> a | b {1, 2, 3, 4, 5, 6} >>> a & b {3, 4} >>> a - b {1, 2} >>> b - a {5, 6} >>> a ^ b {1, 2, 5, 6}
Porovnávať možno aj celé množiny: a <= b znamená „a je podmnožinou b“ (každý prvok a je aj v b).
>>> {1, 2} <= {1, 2, 3} True >>> {1, 4} <= {1, 2, 3} False >>> {3, 2, 1} == {1, 2, 3} True
Dve množiny sa rovnajú, ak majú rovnaké prvky – na poradí zápisu nezáleží.
5Prechádzanie množiny
Cyklus for prejde všetky prvky, ale v nepredvídateľnom poradí. Ak na poradí záleží (napríklad pri výpise), prechádzaj sorted(m):
Výstup:
známka 1
známka 2
známka 36Riešené úlohy
6.1Rôzne písmená v texte
Zadanie: Zisti, koľko rôznych písmen obsahuje veta, a vypíš ich abecedne. Zisti aj, ktoré písmená anglickej abecedy v nej chýbajú.
Riešenie: Množina písmen vznikne z textu po odstránení medzier a interpunkcie. Chýbajúce písmená sú rozdiel celej abecedy a písmen vety.
Výstup:
16 rôznych písmen: abdejklmnorstzéč
chýbajú: cfghipquvwxyVeta, ktorá obsahuje všetky písmená abecedy, sa volá pangram – pre ňu by rozdiel vyšiel prázdny.
6.2Lotéria
Zadanie: Vyžrebuj 6 rôznych čísel od 1 do 49. Potom ich porovnaj so zadaným tipom a vypíš, koľko čísel tip uhádol.
Riešenie: Náhodné čísla pridávame do množiny, kým ich nie je 6 – opakované číslo sa do množiny nepridá, takže na konci máme istotu, že sú všetky rôzne. Počet uhádnutých čísel je veľkosť prieniku. (V ukážke je pevne nastavené random.seed.)
Výstup:
Vyžrebované: [9, 16, 24, 35, 38, 39]
Tip: [3, 11, 17, 25, 31, 42]
Uhádnuté: [] – 0 číslaModul random má na to aj hotovú funkciu: random.sample(range(1, 50), 6) vráti 6 rôznych čísel.
6.3Spoločné záujmy
Zadanie: Dve osoby, A a B, vymenovali svoje záujmy. Vypíš spoločné záujmy, záujmy, ktoré má iba A, a všetky záujmy dohromady.
Výstup:
spoločné: ['hudba', 'programovanie']
iba A: ['futbal', 'šach']
všetky: ['futbal', 'hudba', 'kreslenie', 'plávanie', 'programovanie', 'šach']6.4Ktoré hodnoty sa opakujú?
Zadanie: Vypíš hodnoty, ktoré sa v zozname vyskytujú viackrát.
Riešenie: Prejdeme zoznam a pamätáme si v množine hodnoty, ktoré sme už videli. Ak hodnotu už poznáme, je to opakovanie.
Výstup:
[4, 7]7Časté chyby
{}nie je prázdna množina, ale prázdny slovník – použiset().- Indexovanie množiny (
m[0]) nie je možné – množina nemá poradie; preveď ju na zoradený zoznam. - Spoliehanie sa na poradie pri výpise – výsledok môže vyzerať inak; na výpis použi
sorted. removeneexistujúceho prvku skončí chybouKeyError; použidiscardalebo najprvin.- Zoznam v množine – prvky musia byť nemenné (čísla, reťazce, n-tice).
Zhrnutie
- Množina
{a, b, c}obsahuje každú hodnotu najviac raz a nemá poradie; prázdna jeset(). set(postupnosť)odstráni duplikáty;lenje počet rôznych hodnôt.add,remove(chyba pri chýbajúcom prvku),discard(bez chyby).x in mje veľmi rýchle – vhodné na časté zisťovanie príslušnosti.a | bzjednotenie,a & bprienik,a - brozdiel,a ^ bsymetrický rozdiel,a <= bpodmnožina.- Na výpis v poradí použi
sorted(m).
Úlohy na precvičenie
- Načítaj vetu a vypíš počet rôznych slov (bez ohľadu na veľké a malé písmená).
- Zisti, či je zadaná veta pangram (obsahuje všetky písmená anglickej abecedy).
- Vygeneruj dve množiny po 10 náhodných čísel od 1 do 20 a vypíš ich prienik a zjednotenie.
- Z dvoch zoznamov mien vypíš mená, ktoré sú iba v jednom z nich.
- Načítaj čísla oddelené medzerou a zisti, či sú všetky rôzne (porovnaj dĺžku zoznamu a množiny).