IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 2 - Tuples, množiny a slovníky v Pythonu

V předchozí lekci, Úvod do kolekcí v Pythonu, jsme zjistili, co jsou v Pythonu kolekce a co znamená pojem genericita.

V tomto tutoriálu kolekcí v Pythonu se zaměříme na tuples, množiny a slovníky. Vysvětlíme si, k čemu se používají a čím se od sebe liší. Popíšeme si také základní metody, které k práci s těmito kolekcemi budeme používat.

Tuples v Pythonu

Tuples (někdy též uspořádané n-tice) se velmi podobají seznamům. Jedná se o sekvence, ve kterých ale položky nelze dále modifikovat. Jednotlivé položky se oddělují čárkou. Deklarujeme je pomocí kulatých závorek:

polozky= (1, 2, 3, 7)
print(polozky)

Výstup:

Konzolová aplikace
(1, 2, 3, 7)

Je tu ale malý háček v případě, že chceme deklarovat tuple s jedinou položkou. Abychom ji odlišili od běžné hodnoty proměnné, musíme za položkou napsat čárku (,):

cislo= (1)
polozky= (1,)
print(cislo)
print(polozky)

Výstup:

Konzolová aplikace
1
(1,)

Kolekci tuple používáme, když potřebujeme někde předat sekvenci a chceme se ujistit, že se náhodou nezmění. Tuples jsou read-only, takže pokud potřebujeme tuple z nějakého důvodu modifikovat, musíme vytvořit novou s takovými položkami, které zrovna potřebujeme. Toho dosáhneme například převodem tuple na seznam a zase zpět:

polozky = (1, 2, 3, 7)
print(polozky)
polozky_seznam = list(polozky)
polozky_seznam[1] = 4
polozky = tuple(polozky_seznam)
print(polozky)

Výstup:

Konzolová aplikace
(1, 2, 3, 7)
(1, 4, 3, 7)

V kódu je důležitá metoda tuple() která na tuple převádí jiné sekvence. N-tice mohou být také sloučeny do sebe prostřednictvím operátoru +. Toto platí pro jakýkoliv typ sekvence:

znamky_leden = (1, 1, 4, 2)
znamky_unor = (5, 3, 1)
znamky = znamky_leden + znamky_unor
print(znamky)

Výsledek:

Konzolová aplikace
(1, 1, 4, 2, 5, 3, 1)

Totéž platí pro seznamy. Nelze však kombinovat seznamy a n-tice bez explicitního převodu na stejný datový typ.

Ke zjištění, kolik položek naše tuple obsahuje, použijeme globální funkci len(). Můžeme použít i funkce min() a max() pro určení nejnižší a nejvyšší hodnoty (prostě jako u každé sekvence v Pythonu). Můžeme také použít operátor in, cyklus for, operátor [] pro indexy atd.

Množiny v Pythonu

Množina neboli set je druh sekvence podobné seznamu s tím rozdílem, že může obsahovat jen unikátní položky (každá položka může být v množině pouze jednou). Což také odpovídá matematické definici pro množiny. Tyto položky nejsou setříděné, což znamená že pořadí položek není udržováno a může se nepředvídatelně změnit. Pro množiny není žádná zvláštní syntaxe jako v případě seznamů či n-tic, vytváříme je jednoduše použitím globální funkce set(), které do parametru vložíme sekvenci (i již existující):

planety = set(("Země", "Mars", "Jupiter", "Saturn", "Uran", "Neptun"))
print(planety)
planety.add("Pluto")
print(planety)
planety.add("Neptun")
print(planety)

Ve výstupu dostaneme:

Konzolová aplikace
{'Jupiter', 'Uran', 'Saturn', 'Mars', 'Neptun', 'Země'}
{'Jupiter', 'Uran', 'Saturn', 'Mars', 'Neptun', 'Země', 'Pluto'}
{'Jupiter', 'Uran', 'Saturn', 'Mars', 'Neptun', 'Země', 'Pluto'}

V ukázce výše jsme vytvořili množinu šesti jmen planet. Dvojité závorky na řádku s funkcí set() znamenají, že jsme předali názvy planet formou n-tice jako parametr této funkci. Pořadí položek není seřazeno podle abecedy, a nezmění se ani po přidání nové položky. To ale není žádná chyba, neboť položky jsou vnitřně udržovány v pořadí, což pomáhá množině efektivně určit jedinečnost každé položky.

Metody množin

Podívejme se na základní metody pro operace s množinami.

Metoda add()

Pomocí metody add() přidáváme položky do množiny. Z předchozího příkladu je zřejmé, že pokud se pokusíme přidat do množiny již jednou obsažený prvek, nevyskočí žádná chyba, ale položka prostě není přidána:

seznam = set(("Karel", "Lida", "Alzbeta"))
seznam.add("Ivo")
seznam.add("Karel")
print(seznam)

Výstup:

Konzolová aplikace
{'Karel', 'Lida', 'Alzbeta', 'Ivo'}

Metody difference() a difference_update()

Jak se dalo čekat, množina poskytuje všechny množinové operace, které známe z matematických tříd. Můžeme se třeba zeptat na rozdíl mezi dvěma množinami. Metoda difference() vrací tento rozdíl dvou množin jako novou množinu. Metoda difference_update() naproti tomu upravuje stávající množinu a odstraní všechny položky z druhé množiny:

mnozinaJedna = {1, 2, 3, 4}
mnozinaDva = {3, 4, 5, 6}
rozdil = mnozinaJedna.difference(mnozinaDva)
print(rozdil)
mnozinaJedna.difference_update(mnozinaDva)
print(mnozinaJedna)

Výstup:

Konzolová aplikace
{1, 2}
{1, 2}

Metody remove(), discard(), a pop()

Všechny z těchto tří metod odstraní vybranou položku z množiny. Metoda remove() vyhodí chybu, pokud se hledaná položka v množině nevyskytuje. Metoda discard() se chová zcela totožně, jen při absenci položky zamýšlené k odstranění chybu nevyvolá. Metoda pop() pak vyjme náhodnou hodnotu z množiny a tu potom vrátí:

mnozina = {5, 10, 15, 20}
mnozina.remove(10)
mnozina.discard(10) # nevyvolá chybu, přestože hodnota 10 už v množině není
print(mnozina.pop())
print(mnozina)

Výstup:

Konzolová aplikace
20
{5, 15}

Metoda intersection()

Tato metoda nám vypočítá průnik dvou množin:

mnozinaJedna = {1, 2, 3, 4, 5}
mnozinaDva = {3, 4, 5, 6, 7}
spolecne_prvky = mnozinaJedna.intersection(mnozinaDva)
print(spolecne_prvky)

Výstup:

Konzolová aplikace
{3, 4, 5}

Metoda isdisjoint()

Určuje, zda dvě množiny nemají žádné společné položky (průnik):

mnozinaJedna = {1, 2, 3, 4, 5}
mnozinaDva = {6, 7, 8, 9, 10}
vysledek = mnozinaJedna.isdisjoint(mnozinaDva)
print(vysledek)

Výstup:

Konzolová aplikace
True

Metody issubset() a issuperset()

Můžeme se zeptat, zda je množina podmnožinou (všechny její položky jsou přítomny v druhé množině) nebo nadmnožinou (jsou v ní přítomny všechny položky druhé množiny) pomocí metod issubset() pro podmnožinu a issuperset() nadmnožinu:

mnozinaJedna = {1, 2, 3, 4}
mnozinaDva = {2, 3, 4, 5}
vysledekSubset = mnozinaJedna.issubset(mnozinaDva)
print(vysledekSubset)
vysledekSuperset = mnozinaJedna.issuperset(mnozinaDva)
print(vysledekSuperset)

Výstup:

Konzolová aplikace
False
False

Metoda clear()

Tato metoda odstraní všechny položky z množiny (vyčistí ji):

mnozinaJedna = {1, 2, 3, 4, 5, 6}
mnozinaJedna.clear()
print(mnozinaJedna)

Výstup:

Konzolová aplikace
set()

Slovníky

Slovník (Dictionary) funguje také podobně jako seznam, až na to, že k němu nepřistupujeme jen pomocí indexů, ale i na základě klíčových hodnot různých avšak neměnných datových typů. Index slovníků nazýváme klíč. Na pořadí jednotlivých položek ve slovníku nezáleží.

Data v sekvenci jsou uložena speciálním způsobem, tzv. hashováním. To nám umožňuje přistupovat k prvkům pomocí klíče mnohem rychleji, než kdybychom je podle této vlastnosti hledali např. v obyčejném seznamu. Zatímco u seznamu je potřeba všechny prvky projít a kontrolovat, zda náhodou jejich vlastnost neodpovídá tomu, co hledáme, slovník dokáže pro prvek sáhnout mnohem rychleji díky výpočtu tzv. hashe (otisku). Můžeme si to představit tak, že máme prvky v obyčejném seznamu. Nejsou však bezprostředně za sebou, nějaké indexy nejsou využité vůbec. Finta spočívá v tom, že jsme schopni z klíče zjistit index prvku pomocí hashovací funkce. Pokud budeme mít ve slovníku uložené zaměstnance a klíčem bude jejich jméno, hashovací funkce nám z "Jan Novák" vrátí např. 114. Sáhneme na 114. prvek a hle, je tam Jan Novák. Nemusíme slovník nijak iterovat.

Slovník deklarujeme stejně jako seznam. Hlavní rozdíl je v tom, že používáme složené závorky a musíme k položkám definovat i jejich klíče. K tomu používáme operátor dvojtečka :. Slovníky jsou tedy použity k uložení hodnot v párech klíč:hodnota (key:value):

oblibeneVeci= {
    'homer': 'koblihy',
    'marge': 'trouba',
    'bart': 'prak',
    'lisa': 'saxofon',
    'maggie': 'dudlik'
}

Zápis položek jsme rozdělili kvůli přehlednosti do více řádků, ale šlo by to i v jednom. Ve slovníku máme pět hodnot: 'kobliha', 'trouba', 'prak', 'saxofon', 'dudlík'. Každá hodnota patří nějakému klíči ('homer', 'marge', 'bart', 'lisa' a 'maggie'). Hodnoty přiřadíme ke klíči pomocí dvojtečky (:) a oddělujeme čárkou, která se většinou píše i za poslední položkou.

Pro práci se slovníkem platí to samé, co jsme si ukazovali u seznamu:

print(f"Homer má rád {oblibeneVeci['homer']}")

Namísto zápisu oblibeneVeci[0] jsme použili klíč typu string. Velkou výhodou použití slovníku je lepší čitelnost, kdy přímo vidíme, jakou hodnotu ze slovníku dostáváme. Zatímco u číselných indexů možná ani nevíme, o jakou hodnotu jde. Každý klíč musí být unikátní, ale hodnoty takové být nemusí. Páry klíč:hodnota mohou být jakékoliv neměnné datové typy. Pokud definujeme stejný klíč ve stejném slovníku vícekrát a s různými hodnotami, bude klíči přiřazena poslední hodnota.

Přidávání položek

Do slovníku můžeme jednoduše přidávat další položky přiřazením nových klíčů:

oblibeneVeci['maggie'] = 'dudlik'
print(f"Homer má rád {oblibeneVeci['homer']}")
print(f"Maggie má ráda {oblibeneVeci['maggie']}")

Stejným způsobem můžeme modifikovat již uložené hodnoty.

Pro zjištění počtu položek ve slovníku použijeme globální funkci len() známou již ze seznamů:

print(f'Počet položek: {len(oblibeneVeci)}')

Pomocí operátoru in se zeptáme, zda slovník obsahuje určitý klíč. V Pythonu 2.x k tomu byla určena metoda has_key(), která je ale nyní zastaralá:

simpson = input("Ahoj, zadej svého oblíbeného Simpsona (z rodiny Simpsonů): ").lower()
if simpson in oblibeneVeci:
    print(f"{simpson} má rád {oblibeneVeci[simpson]}.")
else:
    print("Hele, tohle není Simpson!")

Výsledek v konzoli:

Konzolová aplikace
Ahoj, zadej svého oblíbeného Simpsona (z rodiny Simpsonů):
homer
homer má rád koblihy.

Metody slovníků

Podobně jako u seznamů existuje i pro slovníky několik dostupných metod. Podívejme se na ty nejdůležitější.

Metoda get()

Metoda get() nabízí další způsob pro získání položky ze slovníku. Hlavní výhodou této metody je, že nevyhodí žádnou výjimku v případě, že hledaný klíč ve slovníku není. Místo toho vrátí hodnotu None nebo některou výchozí hodnotu, specifikovatelnou ve druhém parametru:

print(oblibeneVeci.get('homer'))
print(oblibeneVeci.get('krusty'))
print(oblibeneVeci.get('krusty', 'nikdo'))

Výsledek:

Konzolová aplikace
koblihy
None
nikdo

Metody values(), keys(), a items()

Pomocí těchto metod můžeme převést slovník na seznam. Můžeme tak vyčlenit hodnoty, klíče nebo dokonce vytvořit seznamy n-tic párů klíč-hodnota:

print(oblibeneVeci.values())
print(oblibeneVeci.keys())
print(oblibeneVeci.items())

Výsledek:

Konzolová aplikace
dict_values(['koblihy', 'trouba', 'prak', 'saxofon', 'dudlík'])
dict_keys(['homer', 'marge', 'bart', 'lisa', 'maggie'])
dict_items([('homer', 'koblihy'), ('marge', 'trouba'), ('bart', 'prak'), ('lisa', 'saxofon'), ('maggie', 'dudlík')])

Metoda clear()

Jak samotný název naznačuje, tato metoda "vyčistí" všechny položky ze slovníku.

Kód je opět k dispozici na konci lekce.

V příští lekci, Vícerozměrné seznamy v Pythonu, se podíváme na dvourozměrné (2D) a vícerozměrné seznamy, včetně příkladů a seznamů "zubatých".


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 92x (3.53 MB)
Aplikace je včetně zdrojových kódů v jazyce Python

 

Předchozí článek
Úvod do kolekcí v Pythonu
Všechny články v sekci
Kolekce v Pythonu
Přeskočit článek
(nedoporučujeme)
Vícerozměrné seznamy v Pythonu
Článek pro vás napsal gcx11
Avatar
Uživatelské hodnocení:
320 hlasů
(^_^)
Aktivity