NOVINKA: Staň se datovým analytikem od 0 Kč a získej jistotu práce, lepší plat a nové kariérní možnosti. Více informací:

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:

Struktura seznamu v Pythonu - Kolekce v Pythonu

(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:

Struktura 2D seznamu v Pythonu - Kolekce v Pythonu

(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:

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 v Pythonu - Kolekce v Pythonu

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):

Pole polí - Kolekce v Pythonu

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:

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

 

Předchozí článek
Slovníky v Pythonu
Všechny články v sekci
Kolekce v Pythonu
Přeskočit článek
(nedoporučujeme)
Kvíz - Tuples, množiny, slovníky a seznamy v Pythonu
Článek pro vás napsal gcx11
Avatar
Uživatelské hodnocení:
660 hlasů
(^_^)
Aktivity