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)
Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.
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)
Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.
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)
Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.
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)
Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.
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)
Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.
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)
Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.
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)
Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.
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)
Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.
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)
Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.
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)
Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.
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)
Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.
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)
Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.
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:
oblibeneVeci= { 'homer': 'koblihy', 'marge': 'trouba', 'bart': 'prak', 'lisa': 'saxofon' } print(f"Homer má rád {oblibeneVeci['homer']}")
Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.
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= { 'homer': 'koblihy', 'marge': 'trouba', 'bart': 'prak', 'lisa': 'saxofon' } oblibeneVeci['maggie'] = 'dudlik' print(f"Homer má rád {oblibeneVeci['homer']}") print(f"Maggie má ráda {oblibeneVeci['maggie']}")
Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.
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ů:
oblibeneVeci= { 'homer': 'koblihy', 'marge': 'trouba', 'bart': 'prak', 'lisa': 'saxofon', 'maggie':'dudlík' } print(f'Počet položek: {len(oblibeneVeci)}')
Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.
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á:
oblibeneVeci= { 'homer': 'koblihy', 'marge': 'trouba', 'bart': 'prak', 'lisa': 'saxofon', 'maggie':'dudlík' } 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!")
Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.
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:
oblibeneVeci= { 'homer': 'koblihy', 'marge': 'trouba', 'bart': 'prak', 'lisa': 'saxofon', 'maggie':'dudlík' } print(oblibeneVeci.get('homer')) print(oblibeneVeci.get('krusty')) print(oblibeneVeci.get('krusty', 'nikdo'))
Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.
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:
oblibeneVeci= { 'homer': 'koblihy', 'marge': 'trouba', 'bart': 'prak', 'lisa': 'saxofón', 'maggie':'dudlík' } print(oblibeneVeci.values()) print(oblibeneVeci.keys()) print(oblibeneVeci.items())
Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.
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 167x (3.53 MB)
Aplikace je včetně zdrojových kódů v jazyce Python