9. díl - Vícerozměrná pole v Pythonu

Python Základní konstrukce Vícerozměrná pole v Pythonu

V minulém tutoriálu o základech Pythonu jsme se podívali na textové řetězcích. Dnešní díl je v sekci základních konstrukcí Pythonu v podstatě bonusový a pojednává o tzv. vícerozměrných polích. Teoreticky můžete rovnou přejít k objektově orientovanému programování, doporučuji však si konec této sekce ještě alespoň projít, abyste měli o zbývajících technikách povědomí. Přeci jen se jedná o dosti základní vědomosti.

Již umíme pracovat s jednorozměrným polem, které si můžeme představit jako řádku přihrádek v paměti počítače.

Pole

(Na obrázku je vidět pole osmi čísel)

Ačkoli to není tak časté, v programování se občas setkáváme i s vícerozměrnými poli a to zejména pokud programujeme nějakou simulaci (např. hru).

Pole polí

Python vlastně vícerozměrná pole nepodporuje. Můžeme si v nich ale stejně vytvořit kolika-rozměrné pole chceme, jelikož 2D pole není vnitřně nic jiného, než pole polí. Situaci si můžeme představit tak, že si vytvoříme pole o pěti prvcích (1. řádek) a každá buňka v tomto řádku v sobě bude obsahovat další pole, reprezentující sloupeček.

Dvourozměrné pole

Dvourozměrné pole 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í, které budete později v zaměstnání tvořit, můžeme si představit, že do 2D pole budeme ukládat informace o obsazenostech sedadel v kinosálu. Situaci bychom si mohli graficky znázornit např. takto:

2D pole

(Na obrázku je vidět 2d pole reprezentující obsazenost kinosálu)

Kinosál by byl v praxi samozřejmě větší, ale jako ukázka nám toto pole postačí. 0 znamená volno, 1 obsazeno. Později bychom mohli doplnit i 2 - rezervováno a podobně. Pro tyto stavy by bylo správnější vytvořit si vlastní datový typ, tzv. výčet (enum), ale s ním se setkáme až později, takže si teď musíme vystačit pouze s čísly.

2D pole vytvoříme v Pythonu následujícím způsobem:

kinosal = []

for i in range(5):
    temp = []
    for j in range(5):
        temp.append(0)
    kinosal.append(temp)

Napřed si vytvoříme prázdný seznam. Poté v prvním cyklu vytvoříme dočasný seznam temp, který postupně naplníme hodnotami a pak ho 5x přidáme do seznamu. Sami si musíme určit, jakými hodnotami budeme seznam naplňovat, v našem případě samými nulami.

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 pole musíme samozřejmě zadat 2 souřadnice. První souřadnice je řádek a druhá je sloupec.

# Prostředek
kinosal[2][2] = 1
# 4. řádek
for i in range(1, 4):
    kinosal[3][i] = 1
# Poslední řádek
for j in range(0, 5):
    kinosal[4][j] = 1

Výpis

Výpis pole opět provedeme pomocí cyklu, na 2d pole budeme potřebovat cykly 2 (jeden nám proiteruje sloupce a druhý řádky). Procházet pole můžeme jednoduše cyklem for in. Nebo můžeme použít i "složitější" způsoby, pokud chceme získat i indexy. Například range(len(seznam)) nebo funkci enumerate().

Cykly zanoříme do sebe tak, aby nám vnější cyklus projížděl řádky a vnitřní sloupce v aktuálním řádku. Po výpisu řádku je nutné odřádkovat. Oba cykly musí mít samozřejmě jinou řídící proměnnou:

for seznam in kinosal:
    for prvek in seznam:
        print(prvek, end="")
    print(end="\n")

Výsledek:

Výpis 2D pole

N-rozměrná pole

Někdy může být příhodné vytvořit si pole o ještě více dimenzích. My všichni si jistě dokážeme představit minimálně 3D pole. 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 by vypadala asi nějak takto:

3D pole

3D pole můžeme vytvořit tím samým způsobem, jako 2D pole, ale více komplikovaněji:

kinosaly = []

for i in range(3):
    kinosal = []
    for j in range(5):
        temp = []
        for k in range(5):
            temp.append(0)
        kinosal.append(temp)
    kinosaly.append(temp)

Kód výše vytvoří 3D pole jako na obrázku. Přistupovat k němu budeme opět přes indexy (hranaté závorky) jako předtím, jen již musíme zadat 3 souřadnice.

kinosaly[3][2][1] = 1

Zkrácená inicializace

Ještě si ukážeme, že i vícerozměrná pole 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á pole

V některých případech nemusíme "plýtvat" pamětí na celou tabulku a můžeme pole vytvořit "zubaté" (anglicky jagged):

Pole polí

Nevýhodou tohoto přístupu je, že musíme pole nepříjemně inicializovat sami. Původní řádek s pěti buňkami sice existuje, ale jednotlivé sloupečky si do něj musíme navkládat sami:

zubate = [[15, 2, 8, 5, 3],
           [3, 3, 7],
           [9, 1, 16, 13],
           [],
           [5]]

A jeho vypsání:

for seznam in zubate:
    for prvek in seznam:
        print(prvek, end=" ")
    print(end="\n")

Na závěr bych rád dodal, že někteří lidé, kteří neumí správně používat objekty, využívají 2D polí 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 vám nyní může zdát, že se jedná o úlohu na 3D pole, ve skutečnosti se jedná o úlohu na obyčejné 1D pole (přesněji seznam) objektů typu Telefon. Ale o tom až u objektově orientovaného programování. Pole si můžete vyzkoušet ještě v cvičení v této sekci.

Příště se podíváme na matematické funkce.


 

Stáhnout

Staženo 25x (946 B)
Aplikace je včetně zdrojových kódů v jazyce python

 

  Aktivity (1)

Článek pro vás napsal gcx11
Avatar
(^_^)

Jak se ti líbí článek?
Celkem (2 hlasů) :
55555


 


Miniatura
Předchozí článek
Funkce a výjimky v Pythonu
Miniatura
Všechny články v sekci
Základní konstrukce jazyka Python
Miniatura
Následující článek
Knihovny math a random

 

 

Komentáře
Zobrazit starší komentáře (7)

Avatar
coells
Redaktor
Avatar
coells:

Pochybuju, že by něco mohlo být lepší, než jsou přednášky z MIT, tak si je projdi a máš ten nejlepší začátek.

 
Odpovědět  +1 17.12.2015 23:17
Avatar
hanpari
Redaktor
Avatar
hanpari:

Na úplný začátek je nejlepší asi toto:
http://www.diveintopython.net/

Coells ti ukázal pokročilejší možnosti, které v Pythonu existují. Otázka je, zda knihovny jako numpy jsou úplně ideální pro začátečníky. V každém případě není od věci zkusit používat Anacondu místo standardní distribuce.
https://www.continuum.io/downloads

Některé věci jsou pak jednodušší :)

 
Odpovědět 18.12.2015 8:56
Avatar
Odpovídá na coells
Milan Šmídl:

Ahoj, diky za info..ja ted jedu podle tohoto https://opentechschool.github.io/…n/index.html
a resim problemy z tohoto( na konci "Problems Set") - dyztak mrkni, min. stoji za to vedet, ze takovy open kurz na MIT existuje..mejte se chlapy:)
http://ocw.mit.edu/…f-a-program/

 
Odpovědět 18.12.2015 9:34
Avatar
Milan Šmídl:

Ahoj prosim mam jeste jeden dotaz, ze jsem tak smely:)
snazim se ted udelat uplne jednoduchej programek, ktery bude na obrazovce vykreslovat uplne jednoduchy fraktal a zasekl jsem se na tom, ze nejsem schopen do funkce která kreslý fraktál(vzdy s o polovinu mensimi parametry)impor­tovat data.Zkratka nejsem schopen udelalt funkci která promenou vzdy v cyklu vynasobí jednou polovinou a to bude argument funkce pro kresleni..Bojim se aby to bylo srozumitelne..Mohl by jsi byt tak hodny a zkusil mi dat nejake rady na zacatek..lehce do me strcit:) Dekuji

 
Odpovědět 29.12.2015 13:12
Avatar
coells
Redaktor
Avatar
Odpovídá na Milan Šmídl
coells:

Milane, bojíš se oprávněně, vůbec netuším, co potřebuješ udělat, ani čemu nerozumíš.
Pokud je to dotaz typu, chci fráktál, ale netuším, jak to udělat, tak si projeď ta videa, o kterých jsme mluvili dříve.

 
Odpovědět 29.12.2015 18:43
Avatar
Odpovídá na coells
Milan Šmídl:

Je mi to jasny:) dam sem kod a uvidis jestli ti to neco rekne, kazdopadne diky za reakci..hezky den

 
Odpovědět 30.12.2015 6:58
Avatar
Odpovídá na coells
Milan Šmídl:
print("milduv fraktal")
import turtle#graficke prostredi, turtle se ovlada jednoduchymi prikazy forward atd.
initial = int(input("zadej základní rozmer"))#

def main():
    turtle.forward(initial)#
    turtle.left(90)
    while True:
           turtle.forward(lengh_computation)
           turtle.penup
           turtle.left(180)
           turtle.forward(lengh_computation)
           urtle.pendown
           turtle.forward(lengh_computation)


def lengh_computation(initial):
    while True:
        initial = initial/2
        return initial

Zde jsou dvě funkce a já bych to rád udělal tak, aby se pri každém cyklu (while ve funkci main)vzdálenost pohybu forward zmenšila o polovinu..Výpočet je ve funkci lengh...Jde o to jak se synchronizuji oba cykly, v podstatě bych si přál aby se pro každý cyklus ve funkci main provedl jeden cyklus výpočtu funkce lengh...
zkusil jsem už všemožné kombinace, ruzně jsem si to vyprintovával, ale asi jsem se nějak zacyklil...pokud jsi z toho alespoň trošku moudrý, tak budu opravdu velmi rád za jakýkoliv feedback...měj se pěkně

Editováno 30.12.2015 10:26
 
Odpovědět 30.12.2015 10:24
Avatar
Odpovídá na Milan Šmídl
Milan Šmídl:

Ps: je mi jasný, že v této podobě to nemůže chodit, je to pouze pro ilustraci co bych jakože rád udělal, zkoušel jsem třeba dvě funkce, kdy výstup jedné je vstupem druhe a naopak a funguji v cyclu, ale neúspěšně..V podstatě nic nefungovalo a už mě to dost flustruje:)

 
Odpovědět 30.12.2015 10:33
Avatar
coells
Redaktor
Avatar
Odpovídá na Milan Šmídl
coells:

Fraktály je jednodušší psát pomocí rekurze.
Funkce zpravidla volá sama sebe s upravenými parametry a končí až ve chvíli, kdy je splněna ukončující podmínka.

import turtle

def vlocka(t, delka):
    if delka < 3:
        return
    t.forward(delka / 3)
    t.left(60)
    vlocka(t, delka / 3)
    t.right(120)
    vlocka(t, delka / 3)
    t.left(60)
    t.forward(delka / 3)

t = turtle.Turtle()

delka = 3 * 3 * 3 * 3 * 3 * 3
t.penup()
t.back(delka / 2)
t.pendown()
vlocka(t, delka)
 
Odpovědět  +2 30.12.2015 11:43
Avatar
Odpovídá na coells
Milan Šmídl:

Díky ti člověče, díky moc..měj se kráásně:)

 
Odpovědět 30.12.2015 12:05
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 17. Zobrazit vše