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í.
Pouze tento týden sleva až 80 % na e-learning týkající se Java. Zároveň využij akce až 80 % zdarma při nákupu e-learningu. Více informací:

Lekce 3 - Vícerozměrné seznamy v Pythonu

V příští lekci, Iterátory, generátory a některé funkce v Pythonu, se podíváme na tuples, množiny a 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

(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

(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) 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, druhé číslo číslo řádku, ale mohli bychom to samozřejmě udělat i obráceně - například matice v matematice mají číslo řádku jako první.

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ý.

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í řádku musíme řádek přerušit. 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

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

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 # Druhý kinosál, třetí řada, čtvrtý sloupec

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]]

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í

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ů typu Telefon.

Kód příkladů je k dispozici na konci lekce.

V další lekci, Iterátory, generátory a některé funkce v Pythonu, si ukážeme lambda funkce, iterátory a generátory a pár vestavěných funkcí.


 

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 338x (909 B)
Aplikace je včetně zdrojových kódů v jazyce Python

 

Předchozí článek
Tuples, množiny a slovníky v Pythonu
Všechny články v sekci
Kolekce v Pythonu
Přeskočit článek
(nedoporučujeme)
Iterátory, generátory a některé funkce v Pythonu
Článek pro vás napsal gcx11
Avatar
Uživatelské hodnocení:
189 hlasů
(^_^)
Aktivity