11. diel - Zoznam v Pythone
V predchádzajúcom cvičení, Riešené úlohy k 9.-10. lekcii Pythona, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.
V dnešnom Python tutoriále 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, kedy v každej máme 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 ľubovôle.
Výhody zoznamu
Možno vás napadá, prečo sa tu zaoberáme zoznamami, keď majú evidentne mnoho obmedzení a existujú lepšie dátové štruktúry. Odpoveď je jednoduchá: zoznamy sú totiž jednoduché. Nemyslíme tým pre nás na pochopenie (to tiež), ale najmä pre Python. Rýchlo sa s nimi pracuje, pretože prvky sú v pamäti jednoducho uložené za sebou. Vďaka dynamickej povahe zoznamov v Pythone navyše nemusia všetky prvky zaberať rovnako miesta. Mnoho vstavaných funkcií a metód v Pythone sa zoznamy 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]
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 ale 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
for
cyklus používa na iteráciu cez prvky v kolekcii, a je teda
ekvivalentom k foreach
cyklu 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
referencie 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. Založme 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 jediný prvok.list_name[m:n]
vyberie prvky v rozsahum
ažn-1
(prvokn
už zahrnutý nie je).list_name[m:n:i]
vyberiem
a 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.
Pokiaľ nie je uvedený prvý prvok, automaticky sa začína od
začiatku zoznamu (index 0
). Pokiaľ nie je uvedený
druhý prvok, výber pokračuje až do konca zoznamu. Pokiaľ
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 pre 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í s využitím 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. S týmito nástrojmi sa stáva práca so zoznamami v Pythone oveľa jednoduchšia a intuitívnejšia.
Metódy pre prácu so zoznamami
Existuje mnoho metód určených priamo pre 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 Simpsonoch:
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ď v zozname budeme mať 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 pre prácu so zoznamami
Python tiež obsahuje niekoľko globálnych funkcií pre 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 ovplyvní:
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é pre prácu iba s číslami), narazíme na chyby. Keď sa
chystáme treba 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 všetky prvky v zozname sú kompatibilné s operáciami, ktoré so zoznamom budeme vykonávať.
To by pre dnešok 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í.