12. diel - Zoznam v Pythone
V predchádzajúcom cvičení, Riešené úlohy k 10.-11. lekcii Pythonu, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.
V dnešnej lekcii Pythonu si predstavíme zoznam. Naučíme sa ho vytvárať, prechádzať ním a pracovať s jeho položkami pomocou funkcií a metód.
Zoznam
Predstavme si, že si chceme uložiť nejaké údaje o viacerých prvkoch.
Napr. chceme v pamäti uchovávať 10 čísel, hracie pole šachovnice alebo
mená 50 užívateľov. Asi nám dôjde, že v programovaní existuje nejaká
lepšia cesta ako začať mechanicky vytvárať premenné user1,
user2 až napr. user50. Nehľadiac na to, že
premenných môžeme potrebovať napríklad 1000! 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 priehradiek, kde máme v každej uložený jeden
prvok. Priehradky sú očíslované tzv. indexy, pričom prvá
priehradka 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. Toto sa obchádzalo tzv. pointermi a vlastnými dátovými štruktúrami, čo často viedlo k chybám pri manuálnej správe pamäte a k nestabilite programu (napr. v C++). 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 z ktorých je možné odoberať položky podľa vlastnej vôle.
Mnoho vstavaných funkcií a metód v Pythone so zoznamami pracuje alebo zoznamy vracia. Ide teda o kľúčovú dátovú štruktúru.
Na hromadnú manipuláciu s prvkami zoznamu sa používajú cykly.
Práca so zoznamom
V nasledujúcich krokoch si ukážeme, ako zoznam deklarovať a ako ho naplniť vlastnými dátami.
Deklarácia a inicializácia zoznamu
Zoznam deklarujeme a inicializujeme pomocou hranatých zátvoriek:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Na slovenskej klávesnici sú hranaté zátvorky ukryté pod Pravým Alt spoločne s klávesmi F a G:

Slovo numbers je samozrejme názov našej premennej. Teraz teda
máme zoznam desiatich hodnôt typu int v premennej
numbers.
Prístup k prvkom zoznamu
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:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(numbers[0])
numbers[5] = 50
print(numbers[5])
V konzole uvidíme výstup:
List output:
1
50
Vytvorenie zoznamu pomocou
funkcie range()
Plniť zoznam ručne dátami by bolo príliš pracné. Poďme teda skúsiť
využiť nám už známu funkciu range() a naplňme zoznam
hodnotami od 1 do 10. Pretože funkcia
range() nevracia zoznam, ale všeobecnú sekvenciu, prevedieme ju
na zoznam pomocou funkcie list():
numbers = list(range(1,11))
Na vytlačenie hodnôt celého zoznamu do konzoly využijeme cyklus
for (ako keď sme tlačili jednotlivé znaky reťazca):
numbers = list(range(1,11))
for number in numbers:
print(number, end = " ")
Takto vyzerá výstup v konzole:
List output using a for loop:
1 2 3 4 5 6 7 8 9 10
V niektorých jazykoch má cyklus for aj variant
foreach (napríklad v C#). V Pythone sa cyklus
for používa na iteráciu cez prvky v kolekcii, a je teda
ekvivalentom k cyklu foreach v iných jazykoch, ako je napr.
C#.
Majme na pamäti, že pomocou cyklu for nie sme schopní
akokoľvek editovať prvky v zozname. V každej iterácii je v cykle
referencia na nemennú položku. Nasledujúci príklad teda
nebude fungovať:
# This code is wrong numbers = list(range(1, 11)) for number in numbers: number += 1 print(numbers)
Zápis number += 1 je skrátená verzia zápisu
number = number + 1. V Pythone sa používa úplne bežne na
skrátenie operácií s premennými. Analogicky funguje aj s ostatnými
operátormi (napr. -=, *=, /= atď.).
Výsledok bude stále:
Attempt to modify list during a for loop:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Funkcia print(numbers) vytlačí obsah zoznamu v
hranatých zátvorkách.
Úprava obsahu zoznamu s
range()
V predchádzajúcom príklade sme totiž zmenili iba hodnoty premenných v cykle, nie hodnoty skutočného zoznamu. Ak chceme upraviť hodnoty zoznamu v cykle, musíme k nim pristúpiť na základe ich indexov:
numbers = list(range(1, 11))
for i in range(len(numbers)):
numbers[i] += 1
print(numbers)
Funkcia len() vracia počet prvkov v zozname.
Reťazcové zoznamy
Pri práci so zoznamami nie sme limitovaní používaním čísel. Vytvorme si ručne zoznam Simpsonovcov:
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, item in enumerate(simpsons):
print(f"{i}: {item}")
Zoznamy často slúžia na ukladanie medzivýsledkov, ktoré sa potom ďalej v programe používajú. Keď nejaký výsledok potrebujeme desaťkrát, stačí ho namiesto desaťkrát spočítať iba raz a uložiť ho do zoznamu. Odtiaľ potom výsledok iba načítame.
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():
numbers = range(10)
print(list(numbers))
print(list(numbers[0:5]))
print(list(numbers[2:8]))
print(list(numbers[1:7:2]))
print(list(numbers[2:9:2]))
print(list(numbers[6:]))
Varianty argumentov:
list_name[m]vyberie jeden prvok.list_name[m:n]vyberie prvky v rozsahumažn-1(prvoknuž zahrnutý nie je).list_name[m:n:i]vyberiema každýi-tý prvok don-1.
Jednotlivé argumenty, ktoré určujú, čo chceme vybrať, je možné aj
vynechať. Môžeme teda napísať [::2], čo nám vyberie každý
druhý prvok v zozname.
Ak nie je uvedený prvý prvok, automaticky sa začína od začiatku
zoznamu (index 0). Ak nie je uvedený druhý prvok, výber
pokračuje až do konca zoznamu. Ak nie je špecifikované, o
koľko prvkov sa má postupovať, východisková hodnota je 1, čo
znamená, že sa vyberá každý prvok v zadanom intervale.
Metódy a funkcie na prácu so zoznamami
Základné operácie so zoznamami v Pythone sme si už predstavili. Teraz sa zameriame na prehĺbenie našich zručností pomocou rôznych metód a funkcií, ktoré Python pre efektívnu a flexibilnú manipuláciu so zoznamami ponúka. Umožňujú nám vykonávať operácie ako triedenie, invertovanie, pridávanie alebo odstraňovanie prvkov a mnoho ďalšieho. Vďaka týmto nástrojom sa stáva práca so zoznamami v Pythone oveľa jednoduchšia a intuitívnejšia.
Metódy na prácu so zoznamami
Existuje mnoho metód určených priamo na prácu so zoznamami. Poďme sa pozrieť na tie najpoužívanejšie. Jednotlivé metódy si predstavíme postupne a uvedieme si aj jednoduché príklady.
Metóda append()
Metóda append() vloží novú položku na koniec zoznamu:
numbers = [2, 3, 16, 21]
numbers.append(13)
print(numbers)
Metóda insert()
Metóda insert() vloží novú položku na konkrétny index v
zozname. Prvým parametrom metódy je index, na ktorý chceme vložiť novú
položku. Druhým parametrom je samotná položka:
numbers = [2, 3, 16, 21]
numbers.insert(1, 10)
print(numbers)
Metóda extend()
Metóda extend() pripojí všetky položky z danej sekvencie do
zoznamu:
numbers = [2, 3, 16, 21]
more_numbers = [13, 18, 24]
numbers.extend(more_numbers)
print(numbers)
Metóda clear()
Metóda clear() odoberie všetky položky zo zoznamu. Rovnaký
výsledok môžeme dosiahnuť zápisom del list_name[:]:
numbers = [2, 3, 16, 21]
numbers.clear()
print(numbers)
Metóda remove()
Metóda remove() odoberie danú položku zo zoznamu. V prípade,
že hľadaná položka nie je v zozname nájdená, metóda remove()
vyvolá výnimku:
numbers = [2, 3, 16, 21]
numbers.remove(3)
print(numbers)
Metóda reverse()
Metóda reverse() otočí poradie položiek v zozname tak, že
prvá položka je teraz posledná, druhá je predposledná atď.:
numbers = [2, 3, 16, 21]
numbers.reverse()
print(numbers)
Metóda count()
Metóda count() vracia počet výskytov danej položky v
zozname:
numbers = [2, 3, 16, 21, 2, 2, 3]
two_count = numbers.count(2)
print(two_count)
Metóda 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 zoradia
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 = " ")
Metóda index()
Metóda index() vracia index prvého výskytu hľadanej
položky. Ak položka nie je nájdená, metóda vyvolá výnimku
ValueError. Metóda si hľadanú položku berie ako parameter.
Ďalej môžeme upresniť dva ďalšie číselné parametre, ktoré určujú
počiatočný a konečný index, medzi ktorými má byť položka hľadaná.
Napríklad umožníme užívateľovi zadať meno Simpsona a povieme mu, na
ktorej pozícii je Simpson uložený. Teraz to pre nás nemá hlbší význam,
pretože položka je iba jednoduchý string. Metóda sa nám však
bude veľmi hodiť vo chvíli, keď budeme mať v zozname uložené
plnohodnotné objekty. Nasledujúci príklad teda berme ako takú prípravu:
simpsons = ["Homer", "Marge", "Bart", "Lisa", "Maggie"]
simpson = input("Hello! What is your favorite character in the Simpsons, you may only choose from the core family members: ")
if simpson in simpsons:
position = simpsons.index(simpson);
print(f"If I had to rank them, that would be no. {position + 1} on my list.")
else:
print("Hey! That's not a Simpson!")
A v konzole vidíme:
Using the index() method:
Hello! What is your favorite character in the Simpsons, you may only choose from the core family members:
Bart
If I had to rank them, that would be no. 3 on my list.
Funkcie na prácu so zoznamami
Python tiež obsahuje niekoľko globálnych funkcií na prácu so zoznamom. Tieto funkcie nie sú špecifické iba pre zoznamy, ale fungujú aj pri iných kolekciách alebo sekvenciách, ako sú n-tice, reťazce, množiny a slovníky.
Funkcia len()
S touto funkciou sme sa už stretli. Vracia nám počet všetkých položiek v zozname:
numbers = [2, 3, 16, 21, 2, 2, 3]
number_of_elements = len(numbers)
print(number_of_elements)
Funkcia min(), max(),
sum()
Jedná sa o matematické funkcie:
min()vracia najmenšiu z položiek v zozname.max()vracia najväčšiu z položiek v zozname.sum()vracia súčet všetkých hodnôt položiek v zozname (pri číselných typoch).
Pozrime sa na príklad:
numbers = [5, 10, 15, 20, 25]
smallest = min(numbers)
print(f"The smallest number in the list is: {smallest}")
largest = max(numbers)
print(f"The largest number in the list is: {largest}")
total = sum(numbers)
print(f"The sum of all numbers in the list is: {total}")
Funkcia 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:
numbers = [2, 8, 1, 5, 3]
sorted_numbers = sorted(numbers)
print(f"Unsorted numbers: {numbers}")
print(f"Sorted numbers: {sorted_numbers}")
Homogénnosť zoznamov v Pythone
Zatiaľ čo v iných programovacích jazykoch bývajú zoznamy obmedzené na uchovávanie prvkov jedného dátového typu, Python nám dovoľuje vytvárať zoznamy, ktoré obsahujú rôzne dátové typy. Napríklad:
mixed_list = [1, "Hello", 3.14, [1, 2, 3]]
Zoznam mixed_list obsahuje celé číslo, reťazec, desatinné
číslo a iný zoznam. Takéto zoznamy sú považované za
nehomogénne. Hoci sú nehomogénne zoznamy v niektorých
situáciách užitočné, často tiež spôsobujú komplikácie. Napríklad ak
sa pokúsime použiť niektoré funkcie, ktoré vyžadujú homogénny zoznam
(napr. funkcie určené na prácu iba s číslami), narazíme na chyby. Keď sa
chystáme napríklad sčítať všetky prvky v zozname, musíme sa uistiť, že
všetky prvky v zozname sú čísla.
Vždy je nutné uistiť sa, že sú všetky prvky v zozname kompatibilné s operáciami, ktoré so zoznamom budeme vykonávať.
To by na dnes stačilo. Môžete sa so zoznamom hrať a experimentovať 😉
V nasledujúcom kvíze, Kvíz - Cykly a zoznamy v Pythone, si vyskúšame nadobudnuté skúsenosti z predchádzajúcich lekcií.
