Späť na hlavnú stránku

Zoznamy v Pythone II

Zoznam (anglicky list, niekedy nazývaný aj pole) je ďalší základný dátový typ v Pythone – umožňuje uložiť viacero hodnôt (aj rôznych typov) pod jedno meno premennej. Zoznam sa zapisuje pomocou hranatých zátvoriek [ ], jednotlivé prvky sa oddeľujú čiarkou. Na rozdiel od reťazca je zoznam meniteľný (mutable). Nadviažeme na základy práce so zoznamami.

Definícia zoznamu, indexovanie a rezy

Pri definícii zoznamu použite správne zátvorky [ ]. S prvkami zoznamu vieme pracovať podobne ako so znakmi reťazca – cez index aj cez rezy (slicing).

Indexovanie zoznamu

Vyskúšajte v Shelli nasledujúce príkazy (analogické ako sme mali pri stringu):

>>> ovocie = ['jablko','hruska','ceresna','ananas','banan','mango']
>>> type(ovocie)
>>> len(ovocie)

Najprv odhadnite, čo bude výsledkom, a potom si to overte:

>>> ovocie[2]
>>> ovocie[6]
>>> ovocie[-1]
>>> ovocie[-6]
>>> dalsie=['dyna','kokos']
>>> ovocie+dalsie

Je zoznam meniteľný?

Z predchádzajúcej kapitoly vieme, že typ String je nemeniteľný (inmutable). Ako je to so zoznamom? Podarí sa vykonať zmenu, t.j. zmeniť napríklad prvý prvok daného zoznamu?

>>> zoznam = ['auto','bubon','ceruzka']
>>> zoznam[0]
>>> zoznam[0]='atom'
>>> zoznam

>>> retazec = 'kreslo'
>>> retazec[0]
>>> retazec[0] = 't'

V reťazcoch sa priamo nedá zmeniť žiadny znak, naproti tomu sme tu zistili, že zoznam je typ meniteľný (tzv. mutable). Ešte otestujte, či v zoznamoch fungujú rezy, podobne ako to fungovalo u reťazcov:

>>> velaovocia = ovocie+dalsie
>>> velaovocia[1:4]
>>> velaovocia[:5]
>>> velaovocia[2:]
>>> velaovocia[:]
>>> velaovocia[1:5:2]
>>> velaovocia[::-1]

Operácie so zoznamami

Vyskúšajte si operácie so zoznamami:

>>> a=[1,2,3]
>>> b=[10,11,12,13,13]
>>> a+b
>>> b+a
>>> 3*a
>>> c=10*[0]
Poznámka:
Niekedy je užitočné mať zoznam „prázdnych" položiek, dosiahneme to napr. príkazom: nic = ['']*5.

Prechádzanie položkami zoznamu

Zoznamom, podobne ako reťazcom, vieme prechádzať cyklom for viacerými spôsobmi:

for i in [1, 2, 3, 'aa', 'bb']:
    print(i)
zoznam=['a','b','c','d','e']
for i in zoznam:
    print(i)
for i in range(len(zoznam)):
    print(zoznam[i])

Cvičenie 1: Iba kladné čísla

Vypíšte zo zoznamu nižšie iba kladné čísla – naprogramujte ;-)

zoznam=[2, -3, 5, 0, 1, -1, 0, -555, -5, 5, 10]
Pomôcka:
Použite podmienený príkaz if v cykle for.

Funkcie na prácu so zoznamom

Vyskúšajte si funkcie len(), max(), min(), sum() na prácu so zoznamom (parametrom funkcie je zoznam, preto do zátvorky treba uviesť s ktorým zoznamom sa má pracovať). Vždy najprv odhadnite, čo vráti daná funkcia, a potom si to v Shelli overte::

>>> a=[1,5,7,8,0,-5,10,25,1,24]
>>> b=['cyril','eduard','adam','albert','emil']

>>> len(a)
>>> max(a)
>>> min(a)
>>> sum(a)
>>> len(b)
>>> max(b)
>>> min(b)
Poznámka:
Funkcie max() a min() vedia porovnávať aj reťazce – podľa abecedného (presnejšie ASCII/Unicode) poradia znakov. Funkcia sum() funguje iba pre zoznam čísel.

Metódy zoznamu

Nad premennou typu zoznam existuje aj niekoľko užitočných metód: .append(), .insert(), .pop(), .reverse(), .sort(). Vyskúšajte si ich na týchto zoznamoch priamo v Shelli:

>>> znamky=['vyborny','chvalitebny','dobry','dostatocny']
>>> cisla=[1,2,3,4]

>>> znamky.append('nedostatocny')
>>> cisla.append(5)
# vloženie prvku na koniec zoznamu

>>> znamky.insert(2,'dvaapol')
>>> cisla.insert(0, '01')
# vloženie prvku na určenú pozíciu do zoznamu (počíta sa od 0)

>>> znamky.pop()
>>> vratilo=cisla.pop()
# odobratie posledného prvku (vráti ho ako výsledok a zoznam zmení)

>>> cisla.pop(0)
>>> co=znamky.pop(2)
# odobratie prvku z určenej pozície (vráti ho ako výsledok – uložíme si to do premennej)

>>> znamky.reverse()
>>> cisla.reverse()
# otočenie prvkov v zozname

>>> znamky.sort()
>>> cisla.sort()
# usporiadanie prvkov v zozname

Úloha MS03-A: Utriedené mená

Vytvorte program, ktorý od užívateľa načíta 10 krstných mien, uloží si ich do zoznamu, následne zoznam utriedi podľa abecedy a vypíše usporiadané mená pod seba.

Ako sú zoznamy uložené v pamäti

Zoznamy sú v pamäti počítača uložené špeciálnym spôsobom (na rozdiel napr. od čísel) – odhalí vám to krokovanie programu. Vyskúšajte si priradenie zoznamu do inej premennej, najprv si to premyslite bez PC a potom overte. V premennej mesta budeme mať uložený zoznam slovenských miest, v premennej chcemVidiet budú mestá, ktoré by som chcel raz navštíviť.

mesta=['Košice', 'Bratislava']
mesta.append('Žilina')
chcemVidiet = mesta
chcemVidiet.append('Viedeň')

Čo bude obsahovať premenná chcemVidiet po týchto príkazoch? Svoj odhad porovnajte so skutočnosťou cez print(chcemVidiet).

Čo bude obsahovať premenná mesta po týchto príkazoch? Svoj odhad porovnajte so skutočnosťou cez print(mesta).

Poznámka:
Dôvod si pozrite pri vizualizácii na stránke pythontutor.com – pod ľavým oknom je „Edit this code...", tam si vložte 4 skúmané príkazy zhora, dajte „Vizualizovať" a postupne krokujte (Next), sledujte, čo sa v pamäti PC deje.

Samostatná kópia zoznamu

Niekedy však potrebujeme mať pravú kópiu zoznamu (aby nedošlo k takýmto nechceným zmenám), vyskúšajte to preto takto cez rezy (porovnajte to aj vizualne na stránke pythontutor.com):

mesta=['Košice', 'Bratislava']
mesta.append('Žilina')
chcemVidiet = mesta[:]  # užitočné použitie rezov!!!
chcemVidiet.append('Viedeň')
print(f'Pamätám si tieto {mesta}.')
print(f'Chystám sa navštíviť {chcemVidiet)')

Operátor in

Ak chceme zistiť, či je nejaký prvok v zozname, môžeme použiť operátor in (prípadne not in). Vyskúšajte si to v Shelli:

>>> cs=[1,1,2,3,3,5,8,13,5,8]
>>> 3 in cs
>>> 4 in cs
>>> 10 not in cs

Úloha MS03-B: Počet výskytov mena

Upravte program z úlohy MS03-A – dodefinujte tam funkciu (namiesto operátora in), ktorá prechádzaním prvkov zoznamu zistí, koľkokrát sa v zozname nachádza jedno konkrétne meno (určí ho užívateľ na vstupe).

Overenie vedomostí

Test – Zoznamy v Pythone

1. Akými zátvorkami sa v Pythone definuje zoznam (list)?

a) okrúhlymi ( )
b) hranatými [ ]
c) zloženými { }
d) úvodzovkami ' '

2. Zoznam ovocie má 6 prvkov (indexy 0 až 5). Čo spôsobí príkaz ovocie[6]?

a) vráti posledný prvok zoznamu
b) vráti prázdny reťazec
c) vyvolá chybu (index je mimo rozsah)
d) vráti hodnotu None

3. Je typ zoznam (list) meniteľný (mutable)?

a) Áno, na rozdiel od reťazca môžeme jeho prvky meniť priamo, napr. zoznam[0]='niečo'
b) Nie, zoznamy sú rovnako nemeniteľné ako reťazce
c) Iba ak obsahuje samé čísla
d) Iba ak ho vytvoríme funkciou list()

4. Čo vráti výraz velaovocia[::-1]?

a) prvý prvok zoznamu
b) zoznam s prvkami v opačnom poradí
c) prázdny zoznam
d) chybu, takýto rez neexistuje

5. Čo vypíše nasledujúci kód?
a=[1,2,3]
print(3*a)

a) [3, 6, 9]
b) [1, 2, 3, 1, 2, 3, 1, 2, 3]
c) chybu, čísla nemožno násobiť zoznamom
d) [1, 2, 3, 3]

6. Po príkaze for i in range(len(zoznam)): print(i) sa vypíšu:

a) hodnoty prvkov zoznamu
b) indexy (čísla 0, 1, 2, ...)
c) dĺžka zoznamu
d) chyba

7. Ktorá metóda vloží nový prvok na koniec zoznamu?

a) .insert()
b) .push()
c) .append()
d) .add()

8. Čo vráti metóda .pop() volaná bez parametra?

a) prvý prvok zoznamu, zoznam nezmení
b) posledný prvok zoznamu a zároveň ho zo zoznamu odoberie
c) náhodný prvok zoznamu
d) dĺžku zoznamu

9. Máme kód:
zoznam = [1,2,3,4,5]
dni = zoznam
dni.append(6)

Čo bude po tomto obsahovať premenná zoznam?

a) čísla 1,2,3,4,5 – bez zmeny
b) čísla 1,2,3,4,5,6 – zoznam sa zmenil tiež, lebo obe premenné odkazujú na ten istý zoznam
c) vyvolá to chybu
d) prázdny zoznam

10. Ako vytvoríme skutočnú (nezávislú) kópiu zoznamu, aby zmena kópie neovplyvnila pôvodný zoznam?

a) novy = povodny
b) novy = povodny[:]
c) novy = povodny.append(povodny)
d) novy = len(povodny)


Späť na hlavnú stránku