Zatiaľ sme mali v každej premennej jednu hodnotu. Čo ak potrebujeme uložiť známky celej triedy, výsledky sto meraní alebo nákupný zoznam? Na to slúži zoznam (typ list) – usporiadaná postupnosť hodnôt uložená pod jedným menom. Zoznamy sú v Pythone asi najpoužívanejšia dátová štruktúra a bez nich sa nezaobíde takmer žiadna maturitná úloha.
Čo sa naučíš
- vytvoriť zoznam, pristupovať k prvkom cez indexy a meniť ich,
- používať metódy zoznamov (
append,insert,pop,remove,sort, …), - prechádzať zoznam cyklom a používať funkcie
len,sum,min,max,sorted, - načítať zoznam zo vstupu a vytvoriť náhodný zoznam,
- zapisovať zoznamy stručne pomocou generátorového zápisu.
1Vytvorenie zoznamu a indexy
Zoznam zapíšeme do hranatých zátvoriek, prvky oddelíme čiarkou:
>>> znamky = [1, 3, 2, 1, 4] >>> mena = ["Ema", "Ján", "Sofia"] >>> prazdny = [] >>> zmiesany = [7, "text", 3.5, True] >>> len(znamky) 5 >>> len(prazdny) 0
Prvky zoznamu sú očíslované indexmi presne ako znaky reťazca – od nuly, záporné od konca:
| index | 0 | 1 | 2 | 3 | 4 |
|---|---|---|---|---|---|
| prvok | 10 | 20 | 30 | 40 | 50 |
| záporný index | -5 | -4 | -3 | -2 | -1 |
>>> z = [10, 20, 30, 40, 50] >>> z[0] 10 >>> z[-1] 50 >>> z[1:3] [20, 30] >>> z[::-1] [50, 40, 30, 20, 10] >>> z[5] IndexError: list index out of range
Rezy fungujú rovnako ako pri reťazcoch a vytvárajú nový zoznam.
1.1Zoznamy sa dajú meniť
Na rozdiel od reťazcov je zoznam meniteľný: prvok môžeme prepísať priradením.
>>> z = [10, 20, 30] >>> z[1] = 99 >>> z [10, 99, 30] >>> z[-1] += 5 >>> z [10, 99, 35]
1.2Zoznam z iných hodnôt
>>> list(range(1, 6)) [1, 2, 3, 4, 5] >>> list("ahoj") ['a', 'h', 'o', 'j'] >>> "a,b,c".split(",") ['a', 'b', 'c'] >>> [0] * 5 [0, 0, 0, 0, 0] >>> [1, 2] + [3, 4] [1, 2, 3, 4] >>> 3 in [1, 2, 3] True
[0] * 5 vytvorí zoznam piatich núl – hodí sa ako počiatočný stav napríklad pre počítadlá. + spojí dva zoznamy do nového, in zistí, či je hodnota v zozname.
2Metódy zoznamov
| Metóda | Čo urobí |
|---|---|
z.append(x) | pridá x na koniec |
z.insert(i, x) | vloží x na index i (ostatné sa posunú) |
z.pop() | odoberie a vráti posledný prvok |
z.pop(i) | odoberie a vráti prvok na indexe i |
z.remove(x) | odstráni prvý výskyt hodnoty x (ak nie je, chyba) |
z.index(x) | vráti index prvého výskytu x (ak nie je, chyba) |
z.count(x) | koľkokrát je x v zozname |
z.sort() | zoradí zoznam (vzostupne; reverse=True zostupne) |
z.reverse() | obráti poradie prvkov |
z.extend(iny) | pridá na koniec všetky prvky iného zoznamu |
z.copy() | vráti kópiu zoznamu |
z.clear() | vymaže všetky prvky |
Výstup:
['jablká', 'chlieb', 'mlieko', 'vajcia']
odobrané: vajcia → ['jablká', 'chlieb', 'mlieko']
['jablká', 'mlieko']
index mlieka: 1Výstup:
[1, 2, 3, 5, 8, 9]
[9, 8, 5, 3, 2, 1]
[1, 2, 3, 5, 8, 9]
počet trojok: 13Prechádzanie zoznamu
Najčastejšie prechádzame priamo prvky:
Výstup:
12.5 °C
14.0 °C
9.5 °C
17.0 °CAk potrebujeme aj pozíciu prvku (alebo chceme prvky meniť), prechádzame indexy:
Výstup:
[47, 40, 52]Pohodlne získaš index aj prvok naraz funkciou enumerate:
Výstup:
1. Ema
2. Ján
3. Sofia4Funkcie pre zoznamy
>>> z = [4, 9, 1, 7] >>> len(z) 4 >>> sum(z) 21 >>> min(z) 1 >>> max(z) 9 >>> sum(z) / len(z) 5.25 >>> sorted(z) [1, 4, 7, 9] >>> sorted(z, reverse=True) [9, 7, 4, 1] >>> z [4, 9, 1, 7]
sorted(z) vráti nový zoradený zoznam a pôvodný nechá tak; z.sort() zoradí priamo pôvodný zoznam. Funkcie min, max a sorted fungujú aj so zoznamom reťazcov (abecedne podľa kódov znakov).
5Kopírovanie: pozor na dve mená pre jeden zoznam
Priradenie b = a nevytvorí kópiu zoznamu – a aj b sú dve mená pre ten istý zoznam:
Výstup:
a = [1, 2, 3, 4]
b = [1, 2, 3, 4]Ak chceš samostatnú kópiu, použi a.copy() alebo rez a[:]:
Výstup:
a = [1, 2, 3]
b = [1, 2, 3, 4]Rovnako to platí pri funkciách: ak funkcii odovzdáš zoznam a ona ho zmení (napr. append), zmena je viditeľná aj mimo funkcie.
6Zoznam zo vstupu
Čísla na jednom riadku – rozdelíme split() a každú časť prevedieme na číslo:
Výstup:
Čísla: 4 8 15 16 23 42 [4, 8, 15, 16, 23, 42] súčet: 108
Čísla na samostatných riadkoch – najprv počet, potom čísla:
Výstup:
Počet: 3 12 7 30 [12, 7, 30]
6.1Náhodný zoznam
Pomocou modulu random (téma Modulárny program) vytvoríme zoznam náhodných čísel. V ukážke je nastavené random.seed(1), aby bol výsledok vždy rovnaký:
Výstup:
[18, 73, 98, 9, 33, 16, 64, 98, 58, 61]
najväčšie: 98 na indexe 27Generátorový zápis
Zoznam, ktorý vzniká z iného zoznamu, sa dá zapísať jedným riadkom – generátorovým zápisom (list comprehension):
[výraz for prvok in postupnosť] alebo s podmienkou [výraz for prvok in postupnosť if podmienka]
>>> [x * x for x in range(1, 6)] [1, 4, 9, 16, 25] >>> [x for x in range(20) if x % 3 == 0] [0, 3, 6, 9, 12, 15, 18] >>> [slovo.upper() for slovo in ["ahoj", "svet"]] ['AHOJ', 'SVET'] >>> [int(c) for c in "2026"] [2, 0, 2, 6]
Zápis je skratkou za tento cyklus:
Výstup:
[1, 4, 9, 16, 25]Načítanie zoznamu čísel zo vstupu sa tak skráti na jeden riadok: cisla = [int(x) for x in input().split()]. Náhodný zoznam: [random.randint(1, 100) for _ in range(10)].
8Riešené úlohy
8.1Priemer a nadpriemerné výsledky
Zadanie: Z bodov z písomky vypočítaj priemer a vypíš, koľko výsledkov je nad priemerom.
Riešenie: Priemer je sum / len. Potom zoznam prejdeme ešte raz a spočítame hodnoty väčšie ako priemer – na to potrebujeme mať všetky čísla uložené, preto zoznam.
Výstup:
Priemer: 37.29
Nad priemerom: 48.2Prvky, ktoré sú v zozname iba raz
Zadanie: Vypíš prvky, ktoré sa v zozname vyskytujú práve raz, v pôvodnom poradí.
Výstup:
[1, 9, 4]8.3Najčastejší prvok
Zadanie: Nájdi hodnotu, ktorá sa v zozname vyskytuje najčastejšie (ak je ich viac, stačí prvá).
Riešenie: Pre každý prvok zistíme jeho počet výskytov a pamätáme si doteraz najlepší. Pre veľké zoznamy je rýchlejšie počítanie cez slovník (téma Slovníky).
Výstup:
5 – 4 krát8.4Druhé najväčšie číslo
Zadanie: Nájdi druhú najväčšiu rôznu hodnotu v zozname (zoznam má aspoň dve rôzne hodnoty).
Riešenie: Zoradíme hodnoty bez opakovania (set odstráni duplikáty – téma Množiny) a vezmeme predposlednú. Bez množiny by sme najprv našli maximum a potom najväčší prvok, ktorý je od neho menší.
Výstup:
Druhé najväčšie: 7
Druhé najväčšie: 78.5Spoločné prvky dvoch zoznamov
Zadanie: Vypíš prvky, ktoré sa nachádzajú v oboch zoznamoch (bez opakovania).
Výstup:
[4, 6, 10]8.6Párne a nepárne, zoradené
Zadanie: Rozdeľ zoznam na párne a nepárne čísla a obidva zoznamy vypíš zoradené.
Výstup:
párne: [8, 10, 22]
nepárne: [1, 3, 7, 15]9Časté chyby
- Index mimo rozsahu (
IndexError): posledný prvok jez[-1]aleboz[len(z) - 1]. z = z.sort(): výsledok jeNone; správne jez.sort()aleboz = sorted(z).b = anamiesto kópie: obe mená menia ten istý zoznam; kópia jea.copy().- Odstraňovanie počas prechádzania: ak v cykle
for x in zvolášz.remove(...), cyklus preskakuje prvky. Radšej vytvor nový zoznam s prvkami, ktoré chceš ponechať:
Výstup:
zle: [4, 5]
dobre: [5]removeaindexhodnoty, ktorá v zozname nie je, skončia chybouValueError– najprv overif x in z:.
Zhrnutie
- Zoznam
[a, b, c]je usporiadaný a meniteľný; indexy a rezy fungujú ako pri reťazcoch. - Pridávanie:
append,insert,extend; odoberanie:pop,remove; ďalejsort,reverse,count,index. - Metódy meniace zoznam vracajú
None– ich výsledok neukladaj. len,sum,min,max,sorted; priemer jesum(z) / len(z).for x in zprechádza prvky,for i in range(len(z))indexy,enumerateoboje.b = anie je kópia – použia.copy().- Generátorový zápis:
[výraz for x in z if podmienka].
Úlohy na precvičenie
- Načítaj čísla oddelené medzerou a vypíš súčet kladných a počet záporných.
- Vytvor zoznam 20 náhodných čísel od 1 do 6 (hody kockou) a vypíš, koľkokrát padla šestka.
- Vypíš zoznam odzadu bez použitia
reversea[::-1](pomocou cyklu). - Načítaj mená hostí, kým sa nezadá prázdny riadok, a vypíš ich abecedne zoradené.
- Posuň prvky zoznamu o jedno miesto doprava:
[1, 2, 3, 4]→[4, 1, 2, 3]. - Napíš funkciu, ktorá vráti index najmenšieho prvku zoznamu (bez
minaindex).