Lekce 4 - Vícerozměrné seznamy v Pythonu
V minulé lekci, Slovníky v Pythonu, jsme se zaměřili na slovníky.
V tomto tutoriálu kolekcí v Pythonu navážeme na základy,
v nichž jsme se seznámili se seznamy. Tyto znalosti teď posuneme do
vyšších dimenzí Naučíme
se pracovat s vícerozměrnými seznamy.
Již tedy umíme pracovat s jednorozměrným seznamem (ve většině ostatních programovacích jazyků se tato struktura označuje pole), který si můžeme představit jako řádku přihrádek v paměti počítače:

(Na obrázku je vidět seznam osmi čísel)
Dvourozměrný seznam
Dvourozměrný seznam si můžeme v paměti představit jako tabulku a mohli bychom takto reprezentovat např. rozehranou partii piškvorek. Pokud bychom se chtěli držet reálných aplikací, můžeme si představit, že do 2D seznamu budeme ukládat třeba informace o obsazenostech sedadel v kinosálu. Situaci bychom si mohli graficky znázornit např. takto:

(Na obrázku je vidět 2d seznam reprezentující obsazenost kinosálu)
Kinosál by byl v praxi samozřejmě větší, ale jako ukázka nám tento
seznam postačí. Obsah buňky 0
znamená volno, 1
obsazeno. Později bychom mohli doplnit i 2
- rezervováno a
podobně.
Python ve skutečnosti neposkytuje žádnou dodatečnou podporu pro vícerozměrné seznamy. To ale nevadí. Můžeme si je totiž jednoduše deklarovat jako seznam seznamů. Definice takového seznamu pro kinosál pak vypadá takto:
kinosal= [] for j in range(5): sloupec= [] for i in range(5): sloupec.append(0) kinosal.append(sloupec)
Nejprve jsme vytvořili prázdný jedno dimenzionální seznam
kinosal
. Následně jsem vytvořili pět dalších seznamů
(představujících sloupce tabulky) pomocí cyklu for
. Sloupce
jsme ihned naplnili pěti nulami použitím vnořeného cyklu a připojili jsme
tento seznam k původnímu jako novou položku.
První číslo představuje číslo sloupce (souřadnici X), druhé číslo číslo řádku (souřadnici Y), což je nejčastější způsob, jak se odkazovat na data v tabulce.
Mohli bychom samozřejmě souřadnice otočit - například matice v matematice mají číslo řádku jako první, v kině také dostaneme první řadu a pak až sedadlo (sloupec). Ale zase bychom to měli opačně, než to v programech většinou je.
Právě jsme tedy vytvořili tabulku plnou nul.
Naplnění daty
Nyní kinosál naplníme jedničkami tak, jak je vidět na obrázku výše.
Protože budeme jako správní programátoři líní, využijeme k vytvoření
řádku jedniček for
cykly Pro přístup k prvku 2D seznamu musíme samozřejmě zadat dvě
souřadnice:
kinosal[2][2] = 1 # střed for i in range(1, 4): # čtvrtá řada kinosal[i][3] = 1 for i in range(5): # poslední řada kinosal[i][4] = 1
Výpis
Výpis seznamu opět provedeme pomocí cyklu. Na 2D seznam budeme potřebovat cykly dva (jeden nám proiteruje sloupce a druhý řádky). Jako správní programátoři nevložíme počet řádků a sloupců do cyklů napevno, jelikož se může změnit.
Již známe funkci len()
takže můžeme jednoduše zjistit,
kolik sloupců je ve vnějším seznamu a kolik položek v tom vnitřním.
Musíme myslet i na to, že vnější seznam může být prázdný.
Jelikož budeme pole vypisovat do konzole, potřebujeme v každém řádku
konzole zobrazit řádek pole. Cykly vnoříme tak, aby vnější cyklus
iteroval přes řádky a vnitřní přes sloupce aktuálního řádku. Po
vytištění celého řádku v konzoli odřádkujeme příkazem
print()
bez parametru. Oba cykly musí mít jinou řídicí
proměnnou:
# deklarace a přidání sloupců
kinosal = []
for j in range(5):
sloupec = []
for i in range(5):
sloupec.append(0)
kinosal.append(sloupec)
# naplnění daty
kinosal[2][2] = 1 # střed
for i in range(1, 4): # čtvrtá řada
kinosal[i][3] = 1
for i in range(5): # poslední řada
kinosal[i][4] = 1
sloupce = len(kinosal)
radky = 0
if sloupce:
radky = len(kinosal[0])
for j in range(radky):
for i in range(sloupce):
print(kinosal[i][j], end ="")
print()
Výsledek:
Konzolová aplikace
00000
00000
00100
01110
11111
Zkrácená inicializace
Ještě si ukážeme, že i vícerozměrné seznamy je možné rovnou inicializovat hodnotami (kód vytvoří rovnou zaplněný kinosál jako na obrázku:
kinosal = [[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 vytvořené pole bude mít ovšem jako první souřadnici řádek a jako druhou sloupec.
Pokud bychom jej chtěli vypsat, můžeme to udělat např. takto:
kinosal = [[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 radek in kinosal :
for sedadlo in radek:
print(sedadlo, end=" ")
print(end="\n")
Výsledek:
Konzolová aplikace
00000
00000
00100
01110
11111
Ani jeden ze systémů souřadnic není lepší než ten druhý, záleží na konkrétním použití.
N-rozměrné seznamy
Někdy může být příhodné vytvořit si seznam o ještě více dimenzích. Všichni si jistě dokážeme představit minimálně 3D seznam. S příkladem s kinosálem se nabízí případ užití, kdy má budova více pater (nebo obecně více kinosálů). Vizualizace pak vypadá třeba takto:

3D seznam vytvoříme tím samým způsobem, jako 2D seznam:
kinosaly = [] for i in range(5): kinosal = [] for j in range(5): temp = [] for k in range(5): temp.append(0) kinosal.append(temp) kinosaly.append(kinosal)
Kód výše vytvoří 3D seznamu jako na obrázku. Přistupovat k němu budeme opět přes indexery (hranaté závorky) jako předtím, jen již musíme zadat tři souřadnice:
kinosaly[3][2][1] = 1 # čtvrtý sloupec, třetí řada, druhý kinosál
Zubaté seznamy
V některých případech nemusíme "plýtvat" pamětí na celou tabulku a můžeme seznam vytvořit "zubatý" (anglicky jagged):

Nevýhodou tohoto přístupu je, že musíme seznam nepříjemně inicializovat sami. Původní řádek s pěti buňkami sice existuje, ale jednotlivé sloupečky si do něj musíme vložit sami:
zubate = [[15, 2, 8, 5, 3], [3, 3, 7], [9, 1, 16, 13], [], [5]]
K jeho vypsání opět využijeme vnořený cyklus:
zubate = [[15, 2, 8, 5, 3],
[3, 3, 7],
[9, 1, 16, 13],
[],
[5]]
for seznam in zubate:
for prvek in seznam:
print(prvek, end=" ")
print(end="\n")
Na závěr dodejme, že někteří lidé, kteří neumí správně používat
objekty, využívají 2D seznamů k ukládání více údajů o jediné entitě.
Např. budeme chtít uložit výšku, šířku a délku pěti mobilních
telefonů. Ačkoli se nyní může zdát, že se jedná o úlohu na 3D seznam,
ve skutečnosti se jedná o úlohu na obyčejný 1D seznam objektů třídy
Telefon
.
Kód příkladů je k dispozici na konci lekce.
V následujícím kvízu, Kvíz - Tuples, množiny, slovníky a seznamy v Pythonu, si vyzkoušíme nabyté zkušenosti z předchozích lekcí.
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 562x (1.13 kB)
Aplikace je včetně zdrojových kódů v jazyce Python