4. diel - Viacrozmerné zoznamy v Pythone
V minulej lekcii, Slovníky v Pythone, sme sa zamerali na slovníky.
V tomto tutoriáli kolekcií v Pythone nadviažeme na základy,
v ktorých sme sa zoznámili so zoznamami. Tieto znalosti teraz posunieme do
vyšších dimenzií
Naučíme sa pracovať s viacrozmernými zoznamami.
Už teda vieme pracovať s jednorozmerným zoznamom (vo väčšine ostatných programovacích jazykov sa táto štruktúra označuje pole), ktorý si môžeme predstaviť ako riadok priehradiek v pamäti počítača:

(Na obrázku je vidieť zoznam ôsmich čísel)
Dvojrozmerný zoznam
Dvojrozmerný zoznam si môžeme v pamäti predstaviť ako tabuľku a mohli by sme takto reprezentovať napr. rozohranú partiu piškvoriek. Ak by sme sa chceli držať reálnych aplikácií, môžeme si predstaviť, že do 2D zoznamu budeme ukladať potrebné informácie o obsadenostiach sedadiel v kinosále. Situáciu by sme si mohli graficky znázorniť napr. takto:

(Na obrázku je vidieť 2D zoznam reprezentujúci obsadenosť kinosály)
Kinosála by bola v praxi samozrejme väčšia, ale ako ukážka nám tento
zoznam postačí. Obsah bunky 0 znamená voľné, 1
obsadené. Neskôr by sme mohli doplniť aj 2 – rezervované a
podobne.
Python v skutočnosti neposkytuje žiadnu dodatočnú podporu pre viacrozmerné zoznamy. To ale nevadí. Môžeme si ich totiž jednoducho deklarovať ako zoznam zoznamov. Definícia takého zoznamu pre kinosálu potom vyzerá takto:
cinema_hall = [] for j in range(5): column = [] for i in range(5): column.append(0) cinema_hall.append(column)
Najprv sme vytvorili prázdny jednodimenzionálny zoznam
cinema_hall. Následne sme vytvorili päť ďalších zoznamov
(predstavujúcich stĺpce tabuľky) pomocou cyklu for. Stĺpce sme
ihneď naplnili piatimi nulami použitím vnoreného cyklu a pripojili sme tento
zoznam k pôvodnému ako novú položku.
Prvé číslo predstavuje číslo stĺpca (súradnicu X), druhé číslo číslo riadku (súradnicu Y), čo je najčastejší spôsob, ako sa odkazovať na dáta v tabuľke.
Mohli by sme, samozrejme, súradnice otočiť – napríklad matice v matematike majú číslo riadku ako prvé, v kine tiež dostaneme najprv radu a až potom sedadlo (stĺpec). Ale zase by sme to mali opačne, než je to vo väčšine programov.
Práve sme teda vytvorili tabuľku plnú núl.
Naplnenie dátami
Teraz kinosálu naplníme jednotkami tak, ako je vidieť na obrázku
vyššie. Pretože budeme ako správni programátori leniví, využijeme na
vytvorenie riadku jednotiek cykly for
Na prístup k prvku 2D zoznamu
musíme samozrejme zadať dve súradnice:
cinema_hall[2][2] = 1 # center for i in range(1, 4): # fourth row cinema_hall[i][3] = 1 for i in range(5): # last row cinema_hall[i][4] = 1
Výpis
Výpis zoznamu opäť vykonáme pomocou cyklu. Na 2D zoznam budeme potrebovať cykly dva (jeden nám preiteruje stĺpce a druhý riadky). Ako správni programátori nevložíme počet riadkov a stĺpcov do cyklov napevno, pretože sa môže zmeniť.
Už poznáme funkciu len() takže môžeme jednoducho zistiť,
koľko stĺpcov je vo vonkajšom zozname a koľko položiek v tom vnútornom.
Musíme myslieť aj na to, že vonkajší zoznam môže byť prázdny.
Keďže budeme pole vypisovať do konzoly, potrebujeme v každom riadku
konzoly zobraziť riadok poľa. Cykly vnoriť tak, aby vonkajší cyklus
iteroval cez riadky a vnútorný cez stĺpce aktuálneho riadku. Po vytlačení
celého riadku v konzole odriadkujeme príkazom print() bez
parametra. Oba cykly musia mať inú riadiacu premennú:
# declaration and adding columns
cinema_hall = []
for j in range(5):
column = []
for i in range(5):
column.append(0)
cinema_hall.append(column)
# filling with data
cinema_hall[2][2] = 1 # center
for i in range(1, 4): # fourth row
cinema_hall[i][3] = 1
for i in range(5): # last row
cinema_hall[i][4] = 1
columns = len(cinema_hall)
rows = 0
if columns:
rows = len(cinema_hall[0])
for j in range(rows):
for i in range(columns):
print(cinema_hall[i][j], end ="")
print()
Výsledok:
Konzolová aplikácia
00000
00000
00100
01110
11111
Skrátená inicializácia
Ešte si ukážeme, že aj viacrozmerné zoznamy je možné rovno inicializovať hodnotami (kód vytvorí rovno zaplnenú kinosálu ako na obrázku:
cinema_hall = [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 1, 1, 1, 0], [1, 1, 1, 1, 1]]
Takto vytvorené pole bude mať však ako prvú súradnicu riadok a ako druhú stĺpec.
Ak by sme ho chceli vypísať, môžeme to urobiť napr. takto:
cinema_hall = [[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 1, 1, 1, 0],
[1, 1, 1, 1, 1]]
for row in cinema_hall :
for seat in row:
print(seat, end=" ")
print(end="\n")
Výsledok:
Konzolová aplikácia
00000
00000
00100
01110
11111
Ani jeden zo systémov súradníc nie je lepší ako ten druhý, záleží na konkrétnom použití.
N-rozmerné zoznamy
Niekedy môže byť vhodné vytvoriť si zoznam s viacerými dimenziami. Všetci si určite dokážeme predstaviť minimálne 3D zoznam. S príkladom s kinosálou môže byť prípad použitie, keď má budova viac poschodí (alebo všeobecne viac kinosál). Vizualizácia potom vyzerá napríklad takto:

3D zoznam vytvoríme tým istým spôsobom, ako 2D zoznam:
cinema_halls = [] for i in range(5): cinema_hall = [] for j in range(5): temp = [] for k in range(5): temp.append(0) cinema_hall.append(temp) cinema_halls.append(cinema_hall)
Kód vyššie vytvorí 3D zoznam ako na obrázku. Pristupovať k nemu budeme opäť cez indexery (hranaté zátvorky) ako predtým, len už musíme zadať tri súradnice:
cinema_halls[3][2][1] = 1 # fourth column, third row, second cinema hall
Zubaté zoznamy
V niektorých prípadoch nemusíme "plytvať" pamäťou na celú tabuľku a môžeme vytvoriť "zubatý" zoznam (anglicky jagged):

Nevýhodou tohto prístupu je, že musíme zoznam nepríjemne inicializovať sami. Pôvodný riadok s piatimi bunkami síce existuje, ale jednotlivé stĺpčeky si do neho musíme vložiť sami:
jagged = [[15, 2, 8, 5, 3], [3, 3, 7], [9, 1, 16, 13], [], [5]]
Na jeho vypísanie opäť využijeme vnorený cyklus:
jagged = [[15, 2, 8, 5, 3],
[3, 3, 7],
[9, 1, 16, 13],
[],
[5]]
for sublist in jagged:
for element in sublist:
print(element, end=" ")
print(end="\n")
Na záver dodajme, že niektorí ľudia, ktorí nevedia správne používať
objekty, využívajú 2D zoznamy na ukladanie viacerých údajov o jedinej
entite. Napr. budeme chcieť uložiť výšku, šírku a dĺžku piatich
mobilných telefónov. Hoci sa teraz môže zdať, že sa jedná o úlohu pre 3D
zoznam, v skutočnosti sa jedná o úlohu pre obyčajný 1D zoznam objektov
triedy Phone.
Kód príkladov je k dispozícii na konci lekcie.
V nasledujúcom kvíze, Kvíz - Tuples, sets, slovníky a zoznamy v Pythone, si vyskúšame nadobudnuté skúsenosti z predchádzajúcich lekcií.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 45x (1.12 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Python
