15. diel - Zoznamy v Pythone
V tomto tutoriále základov programovania v jazyku Python sa naučíme pracovať so zoznamami. Naučíme sa ich vytvárať, prechádzať a pracovať s ich položkami pomocou užitočných funkcií a metód.
Zoznamy
Predstavme si, že si chceme uložiť nejaké údaje o viacerých prvkoch.
Napr. chceme v pamäti uchovávať 10 čísel, políčka šachovnice alebo mená
50 užívateľov. Asi je zrejmé, že v programovaní bude nejaká lepšia
cesta, než začať mechanicky vytvárať premenné uzivatel1
,
uzivatel2
, ... až uzivatel50
. Nehľadiac na to, že
ich môžeme potrebovať napríklad 1000. A ako by sa v tom potom hľadalo?
Brrr, takto nie:)
Ak potrebujeme uchovávať väčšie množstvo premenných rovnakého
typu, tento problém nám rieši zoznam. Môžeme si
ho predstaviť ako množstvo priehradok, kde v každej máme uložený jeden
prvok. Priehradky sú očíslované tzv. indexy, pričom prvá má index
0
.
Programovacie jazyky sa veľmi líšia v tom, ako so zoznamom pracujú. V niektorých jazykoch (najmä starších, kompilovaných) nebolo možné za behu programu vytvoriť zoznam s dynamickou veľkosťou (napr. mu dať veľkosť podľa nejakej premennej). Zoznam sa musel deklarovať s konštantnou veľkosťou priamo v zdrojovom kóde. Tieto druhy zoznamov sa často označujú ako pole. Ako vieme, Python je interpretovaný programovací jazyk, takže neposkytuje pole s pevnou veľkosťou. Namiesto toho dostávame dynamické zoznamy, do ktorých môžeme pridávať a odoberať položky podľa ľubovôle.
Na hromadnú manipuláciu s prvkami zoznamu sa používajú cykly.
Deklarácia zoznamu
Zoznam deklarujeme pomocou hranatých zátvoriek:
cisla = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Premenná cisla
je samozrejme názov nášho zoznamu. Teraz teda
máme zoznam desiatich hodnôt typu int
v premennej
cisla
. K jednotlivým prvkom uloženým v zozname
pristupujeme prostredníctvom indexov vo vnútri hranatých
zátvoriek, prvým indexom je vždy 0
:
print(cisla[0]) # cisla[0] = 1
Vytvorenie zoznamu pomocou
funkcie range()
Naplniť zoznam hodnotami ručne môže byť príliš zdĺhavé. Poďme teda
skúsiť využiť nám už známe funkcie range()
a naplňme zoznam
hodnotami od 1 do 10. Pretože ale range()
nevracia zoznam, ale
všeobecnú sekvenciu, prevedieme ju na zoznam pomocou funkcie
list()
:
cisla = list(range(1,11))
Na vytlačenie hodnôt celého zoznamu do konzoly využijeme cyklu
for
(ako keď sme tlačili jednotlivé znaky reťazca):
cisla = list(range(1,11))
for cislo in cisla:
print(cislo, end=" ")
Výsledok vidíme:
Konzolová aplikácia
1 2 3 4 5 6 7 8 9 10
Funkciu range()
samozrejme môžeme použiť aj s parametrami.
Syntax si zopakujme:
- range(n) - vráti čísla od nuly do n-1 (teda do n, ktoré už zahrnuté nie je)
- range(m, n) - vráti čísla od m do n-1
- range(m, n, i) - vráti čísla od ma každé ďalšie i-té číslo do n-1
cisla = list(range(1, 10, 2))
print(cisla)
Jeho výstup v konzole:
Konzolová aplikácia
[1, 3, 5, 7, 9]
V niektorých jazykoch je cyklus for
tiež známy ako
foreach
(napríklad v C#). Majme na pamäti,
že nie sme schopní pomocou cyklu for
nijako editovať prvky v
zozname. V každej iterácii je v cykle referencie na nemennú
položku, nasledujúci príklad teda nebude
fungovať:
# Tento kód je chybný cisla= list(range(1, 11)) for cislo in cisla: cislo+= 1 print(cisla)
Funkcia print(cisla)
tiež vytlačí obsah zoznamu,
ale v hranatých zátvorkách.
Výsledok bude stále:
Konzolová aplikácia
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Úprava obsahu zoznamu s
funkciou range()
V predchádzajúcom príklade sme totiž zmenili iba hodnoty premenných v cykle, nie skutočného zoznamu. Ak chceme upraviť hodnoty zoznamu v cykle, musíme k nim pristúpiť na základe ich indexov:
cisla= list(range(1, 11))
for i in range(len(cisla)):
cisla[i] += 1
print(cisla)
Výsledok potom bude vyzerať takto:
Konzolová aplikácia
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
Funkcia len()
, ktorú už dobre poznáme, nám
vracia počet prvkov v zozname.
Reťazcové zoznamy
Pri práci so zoznamami nie sme limitovaní len používaním čísel:
simpsons = ["Homer", "Marge", "Bart", "Lisa", "Maggie"]
Na iteráciu položiek v zozname môžeme okrem funkcie range()
použiť aj funkciu enumerate()
. Jej výhodou je, že nám vráti
ako index položky, tak aj položku samotnú:
simpsons = ["Homer", "Marge", "Bart", "Lisa", "Maggie"]
for i, prvek in enumerate(simpsons):
print("%d: %s" % (i, prvek))
Výstup v konzole:
Konzolová aplikácia
0: Homer
1: Marge
2: Bart
3: Lisa
4: Maggie
Zoznamy sa často využívajú na ukladanie medzivýpočtov, ktoré využívame v programe neskôr. Keď potrebujeme výsledok napr. 10x, vypočítame ho len raz a uložíme do zoznamu. Potom môžeme jednoducho vypísať výsledok.
Orezávanie
V Pythone je možné dostať len "orezanú" časť zoznamu. Syntax je
podobná ako v prípade prístupu k položkám. Len upresníme viac argumentov,
podobne ako pri funkcii range()
.
cisla = range(10)
print(list(cisla))
print(list(cisla[0:5]))
print(list(cisla[2:8]))
print(list(cisla[1:7:2]))
print(list(cisla[2:9:2]))
print(list(cisla[6:]))
A takto vyzerá výstup:
Konzolová aplikácia
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4]
[2, 3, 4, 5, 6, 7]
[1, 3, 5]
[2, 4, 6, 8]
[6, 7, 8, 9]
Vidíme teda teda niekoľko možností, ako argumenty využiť:
- názov_zoznamu[m] - vyberie jediný prvok
- názov_zoznamu[m:n] - vyberie prvky v rozsahu m až n-1 (prvok n už zahrnutý nie je)
- názov_zoznamu[m:n:i] - vyberie ma každý i-tý prvok do n-1
0
) .
Ak nie je zadaný druhý prvok, berie sa koniec zoznamu. A ak nie je zadané, o
koľko prvkov chceme postupovať, je východiskový 1, teda sa vezme každý
prvok v zadanom intervale.
Metódy pre prácu so zoznamami
Existuje niekoľko metód určených na prácu so zoznamami. Poďme sa na ne pozrieť.
append()
Metóda append()
vloží novú položku na koniec zoznamu:
cisla = [2, 3, 16, 21]
cisla.append(13)
print(cisla)
V konzole vyzerá výstup takto:
Konzolová aplikácia
[2, 3, 16, 21, 13]
pop()
Metóda pop()
vracia poslednú položku zoznamu a zároveň ho
zo zoznamu vyberie:
cisla = [2, 3, 16, 21]
print(cisla.pop())
print(cisla)
Výstup v konzole:
Konzolová aplikácia
21
[2, 3, 16]
insert()
Metóda insert()
vloží položku na danú pozíciu. Prvým
parametrom metódy je index a druhým je položka, ktorá má byť vložená na
tento index. Ostatné položky sa posunú.
extend()
Metóda extend()
pripojí všetky položky z danej sekvencie do
zoznamu.
clear()
Metóda clear()
odoberie všetky položky zo zoznamu. Rovnaký
výsledok môžeme dosiahnuť zápisom del seznam[:]
remove()
Metóda remove()
odoberie danú položku zo zoznamu. Táto
funkcia vyvolá výnimku v prípade, že
hľadaná položka nie je v zozname nájdená.
reverse()
Metóda reverse()
otočí poradie položiek v zozname tak, že
prvá položka je teraz posledná, druhá je predposledná, atď.
count()
Metóda count()
vracia počet výskytov danej položky v
zozname.
sort()
Metóda sort()
zoznam zoradí. Je dokonca tak múdra, že
pracuje podľa toho, čo máme v zozname uložené. Textové reťazce triedia
podľa abecedy, čísla podľa veľkosti, atď. Skúsme si zotriediť a
vypísať našu rodinku Simpsonovcov:
simpsons = ["Homer", "Marge", "Bart", "Lisa", "Maggie"]
simpsons.sort()
for s in simpsons:
print(s, end = " ")
Takto vyzerá výstup v konzole:
Konzolová aplikácia
Bart Homer Lisa Maggie Marge
Môžeme si skúsiť vytvoriť zoznam s náhodnými číslami a ten potom zotriediť.
index()
Táto metóda vracia index prvého výskytu hľadanej položky. Ak položka
nie je nájdená, vyvolá výnimku ValueError
. Metóda si berie
hľadanú položku ako parameter. Ďalej môžeme upresniť dva ďalšie
číselné parametre určujúce počiatočný a konečný index, medzi ktorými
má byť položka hľadaná. Umožníme napríklad užívateľovi zadať meno
Simpsona a povieme mu, na akej pozícii je uložený. Teraz to pre nás nemá
hlbší význam, pretože položka len jednoduchý string
. Bude sa
nám to však veľmi hodiť vo chvíli, keď v zozname budeme mať uložené
plnohodnotné objekty. Berme to teda ako takú prípravu:
simpsons = ["Homer", "Marge", "Bart", "Lisa", "Maggie"]
simpson = input("Ahoj, zadaj svojho obľúbeného Simpsona (z rodiny Simpsonovcov):")
if simpson in simpsons:
position = simpsons.index(simpson);
print("Jo, to je môj%d. najobľúbenejšie Simpson!" % (position + 1))
else:
print("Hele, toto nie je Simpson!")
V konzole potom uvidíme:
Konzolová aplikácia
Ahoj, zadej svého oblíbeného Simpsona (z rodiny Simpsonů): Bart
Jo, to je můj 3. nejoblíbenější Simpson!
Funkcie pre prácu so zoznamami
Python taktiež obsahuje niekoľko globálnych funkcií pre prácu so zoznamom. Tieto funkcie tiež fungujú na iných dátových typoch zoznamu.
len()
S touto funkciou sme sa už stretli. Vracia nám počet všetkých položiek v zozname.
min()
, max()
,
sum()
Jedná sa o matematické funkcie:
min()
- Vracia najmenšiu z položiek v zoznamemax()
- Vracia najväčšiu z položiek v zoznamesum()
- Vracia súčet všetkých hodnôt položiek v zozname (u číselných typov)
sorted()
Táto funkcia nápadne pripomína metódu sort()
, ale na rozdiel
od nej vracia zotriedenú kópiu pôvodného zoznamu bez toho,
aby ho akokoľvek ovplyvnila.
all()
Funkcia vracia True
ak sú všetky položky zoznamu vyhodnotené
ako True
(nenulové čísla, neprázdne reťazce aj zoznamy
atď.):
seznam_1 = [1, 3, 2, 0, 5] # false - obsahuje číslo 0
seznam_2 = [6, 4, 5, 1, 2] # true - obsahuje jen nenulová čásla
print(all(seznam_1))
print(all(seznam_2))
Výsledok:
Konzolová aplikácia
False
True
Akékoľvek nenulové číslo (vrátane záporných) je vždy
vyhodnotené ako True
!
any()
Funkcia vracia True
, ak je v zozname aspoň jedna hodnota
vyhodnotená ako True
(nenulové čísla, neprázdne reťazce aj
zoznamy atď.):
seznam_1 = [1, 3, 2, 0, 5] # false -obsahuje číslo 0
seznam_2 = [6, 4, 5, 1, 2] # true - obsahuje len nenulové čísla
seznam_3 = [] # false - prázdny zoznam
print(any(seznam_1))
print(any(seznam_2))
print(any(seznam_3))
Pozrime sa na výstup:
Konzolová aplikácia
True
True
False
del()
Touto funkciou môžeme odstrániť položky zoznamu:
cisla = [1, 3, 2, 0, 5]
del cisla[1]
print(cisla)
Získame:
Konzolová aplikácia
[1, 2, 0, 5]
Tiež môžeme použiť aj zápis:
cisla = [1, 3, 2, 0, 5]
del cisla[1:3]
print(cisla)
Výsledok:
Konzolová aplikácia
[1, 0, 5]
Tak, a to už by pre dnešok stačilo. Určite ale by bolo vhodné sa so zoznamami samostatne trošku pohrať a experimentovať 😉 Príklady použitia zoznamov sú k dispozícii na stiahnutie.
V nasledujúcom cvičení, Riešené úlohy k 14. lekcii Pythonu, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.