05 Loeng
Nädala teema: Listid ja sõnastikud Pythonis
“Do not repeat yourself” printsiip
Enne kui hakkame uusi andmestruktuure õppima, meenutame midagi olulist...
Nägite eelmisel nädalal praktikumis, et sama koodi korduvalt kopeerimine on tüütu ja ajakulukas! Ilmselt mõtlesite: "Kas tõesti peab sama asja viis korda kirjutama?"
Õnneks programmeerimises kehtib DRY printsiip nagu te ka kodus lugesite: Don't Repeat Yourself ehk "Ära kordu". See tähendab: kirjuta kood üks kord ja kasuta seda kuus korda!
Mõelge: mitu korda te eelmisel nädalal kirjutasite faili avamise ja sisselugemise koodi? Sama koodi, sama vigu, sama ajakulu. Kirjutage üks kord funktsioon loe_tekst_failist(failinimi) ja kasutage seda igal pool!
See nädal loome eraldi faili ning eraldi funktsioon ning vajadusel toome selle enda programmi sisse ehk impordime. See annab teile:
- Vähem kopeerimist - keskendute ülesande sisule, mitte kordamisele
- Vähem vigu - kord testitud funktsioon töötab alati õigesti
- Kiirem arendus -
importja kasuta, nii lihtne see on
- Modulaarsuse oskus - üks olulisemaid programmeerimise oskusi
Aga enne kui hakkame funktsioone importima, vajame uut tööriista - liste. Sest kuidas me muidu hoiame hulka andmeid korraga?
Sissejuhatus – mis asi on list?
Pythonis on list (eesti keeles: järjend) muudetav, järjestatud kogum väärtusi, mida saab töödelda tsüklite, funktsioonide ja operatsioonide abil. Listid on ühed kõige kasulikumad andmestruktuurid, sest nendega saab:
- Talletada mitu väärtust ühes muutujas
- Muuta, lisada ja eemaldada väärtusi jooksvalt
- Sorteerida ja otsida andmeid
📌 List on nagu vanaema riiul, kuhu saad panna erinevaid asju ritta – sa saad asju juurde panna, välja võtta või ümber tõsta. Purkidel on alati oma kindel järjekord.

List luuakse nurksulgude [ ] abil. Elemendid eraldatakse komadega.
Näiteks:
tühi_list = []
numbrid = [1, 2, 3, 4]
segatud = ["Tere", 42, 3.14, True]
Märkus: programmeerimises loendatakse nullist. Seega list[0] on esimene element ehk antud näitels list[0] = “Tere” ja list[1] on teine ehk list[11] = 42 jne.

Uuendame natukene meie näidet:
# List 0
empty_list = [] # Loome uue listi
print(f"Empty list: {empty_list}") # Prindime muutuja empty_list
# Vaatame mis type on muutuja empty_list
print(f"Empty list type: {type(empty_list)}")
# List 1
numbrid = [1, 2, 3, 4] # Loome uue listi
print(f"List numbrid: {numbrid}") # Prindime muutuja numbrid
# Prindime listis oleva teise elemendi
print(f"List numbrid, index 1: {numbrid[1]}")
# List 2
segatud = ["Tere", 42, 3.14, True] # Loome uue listi
print(f"Segatud list: {segatud}") # Prindime muutuja segatud
# Prindime listis oleva esimese elemendi
print(f"Segatud list, index 0: {segatud[0]}")
# Prindime listis olema viienda elemendi
print(f"Segatud list, index 5: {segatud[5]}")Näite output:
Empty list: []
Empty list type: <class 'list'>
List numbrid: [1, 2, 3, 4]
List numbrid, index 1: 2
Segatud list: ['Tere', 42, 3.14, True]
Segatud list, index 0: Tere
Traceback (most recent call last):
File "/Users/gregorkokk/test.py", line 29, in <module>
print(f"Segatud list, index 5: {segatud[5]}")
~~~~~~~^^^
IndexError: list index out of rangeNäeme, et:
- Tühi list -
empty_list = []loob tõepoolest tühja listi jatype()funktsioon kinnitab, et see on<class 'list'>tüüpi.
- Numbrite list -
numbridsisaldab nelja elementi: [1, 2, 3, 4]. Kui küsimenumbrid[1], saame väärtuse2, sest Python alustab indekseerimist nullist:- Index 0 → 1
- Index 1 → 2 ✓
- Index 2 → 3
- Index 3 → 4
- Segatud list -
segatudsisaldab erinevat tüüpi elemente: string, täisarv, ujukomaarv ja tõeväärtus.segatud[0]annab meile esimese elemendi "Tere".
- IndexError - Programm jooksis kokku, kui üritasime pääseda ligi
segatud[5]elemendile. See juhtus sellepärast, et:segatudlistis on ainult 4 elementi (indeksid 0, 1, 2, 3)
- Me üritasime pääseda ligi 6. elemendile (index 5)
- Python viskas
IndexError: list index out of rangevea, sest sellist indeksit ei eksisteeri
NB!
Listide indekseerimine alustab alati nullist, seega 4-elemendiline list omab indekseid 0, 1, 2, 3.
Põhitegevused listidega
Operatsioonid listi indeksitega
Listi iga elemendi juurde pääseb indeksi kaudu. Pythonis algab indeks nullist, seega esimesele elemendile viitab list[0], teisele list[1] jne. Lisaks saab kasutada negatiivseid indekseid, et liikuda tagantpoolt: list[-1] on viimane, list[-2] eelviimane jne.
a = ["esimene", "teine", "kolmas", "neljas"]
print(a[0]) # "esimene"
print(a[2]) # "kolmas"
print(a[-1]) # "neljas"
a[0]→ esimene element
a[-1]→ viimane element
a[-2]→ eelviimane element
a[1:3]→ viilutamine (slice): tagastab 2. ja 3. elemendi (["teine", "kolmas"])
a[:2]→ esimesed kaks
a[2:]→ kõik alates kolmandast
Viilutamise näide:
päevad = ["E", "T", "K", "N", "R", "L", "P"]
print(päevad[0]) # "E"
print(päevad[-1]) # Hangime viimane elemendi ehk "P"
print(päevad[-2]) # Hangime eelviimase elemendi "L"
print(päevad[1:4]) # ["T", "K", "N"]
print(päevad[:3]) # ["E", "T", "K"]
print(päevad[4:]) # ["R", "L", "P"]NB! Kui kasutada viilutamist (slice), siis esimene indeks võetakse arvesse, aga viimast indekst enam ei võeta arvesse!
Muudame viilutamis näidet nii, et prindime esimesed kaks elementi:
päevad = ["E", "T", "K", "N", "R", "L", "P"]
print(päevad[:2])Mis on selle väljund?
['E', 'T']Õige vastus on ['E', 'T']
Meetodid listidega
Vaatame, kuidas andmeid lisada ja eemaldada. Loendist andmete eemaldamiseks on mitu võimalust. See, mida kasutate, sõltub olukorrast.
Lisa uus element olemasolevasse järjendisse
Loendiobjektidel on mitu kasulikku sisseehitatud meetodit, millest üks on lisamismeetod ehk append() . Loendile lisamismeetodi kutsumisel lisame objekti loendi lõppu.
Näide append()
my_list = [1, 2]
my_list.append('a')
print(my_list)
my_list.append(4)
print(my_list)Output append()
[1, 2, 'a']
[1, 2, 'a', 4]Eemalda konkreetne väärtus järjendist
Kui soovite järjendist konkreetse väärtuse eemaldada, kasutage meetodit remove(). See meetod eemaldab loendist antud objekti esimese esinemise.
Näide remove()
my_list = [1, 2, 3, 2, 5]
my_list.remove(2)
print(my_list)
my_list.remove(2)
print(my_list)
my_list.remove(2)Output remove()
[1, 3, 2, 5]
[1, 3, 5]
Traceback (most recent call last):
File "/Users/gregorkokk/test.py", line 8, in <module>
my_list.remove(2)
~~~~~~~~~~~~~~^^^
ValueError: list.remove(x): x not in listNäeme, et:
append()meetod töötab järjestikku → Iga kord kui kutsumemy_list.append(), lisatakse uus element alati listi lõppu:- Alguses:
[1, 2]
- Pärast
append('a'):[1, 2, 'a']
- Pärast
append(4):[1, 2, 'a', 4]
- Alguses:
remove()meetod eemaldab ainult esimese leitud väärtuse:- Algne list:
[1, 2, 3, 2, 5](sisaldab kahte "2"-te)
- Esimene
remove(2): eemaldab esimese "2" →[1, 3, 2, 5]
- Teine
remove(2): eemaldab järgmise "2" →[1, 3, 5]
- Kolmas
remove(2): VIGA! → listis pole enam ühtegi "2"-te
- Algne list:
- ValueError tekib, kui üritame eemaldada elementi, mida listis ei ole. Python ütleb:
ValueError: list.remove(x): x not in list→ see tähendab, et "x" (meie puhul "2") ei leidu enam listist.
NB!
remove() meetod eemaldab alati ainult esimese leitud väärtuse ja viskab vea, kui elementi üldse ei leidu. Kui tahad kõik sama väärtusega elemendid eemaldada, pead remove() meetodit mitu korda kutsuma või kasutama muud lähenemist.
Veel näiteid:
loendid = ["õun", "pirn", "ploom"]
print(loendid[0]) # "õun"
print(loendid[1]) # "pirn"
print(loendid[2]) # "ploom"
print(loendid[-1]) # "ploom"
loendid.append("banaan") # Lisab lõppu
print(loendid) # ["õun", "pirn", "ploom", "banaan"]
loendid.remove("pirn") # Eemaldab esimese esinemise
print(loendid) # ["õun", "ploom", "banaan"]
Kui remove() ei leia väärtust, viskab see ValueError:
fruits = ["õun", "pirn"]
try:
fruits.remove("ploom")
except ValueError:
print("Elemendi eemaldamine ebaõnnestus!")1. Elementide lisamine loendisse
| Meetod | Kirjeldus | Näide | Märkus |
|---|---|---|---|
append(x) | Lisab ühe elemendi loendi lõppu | loend.append("pirn") | Kõige sagedamini kasutatav |
extend(iterable) | Lisab kõik teise loendi/iteraabli elemendid | loend.extend(["õun", "ploom"]) | Lisab mitu väärtust korraga |
insert(i, x) | Lisab elemendi kindlale indeksile | loend.insert(1, "banaan") | Nihutab olemasolevad edasi |
2. Elementide eemaldamine loendist
| Meetod | Kirjeldus | Näide | Märkus |
|---|---|---|---|
remove(x) | Eemaldab esimese esinemise väärtusest | loend.remove("pirn") | Viga, kui väärtust ei leita (ValueError) |
pop(i) | Eemaldab ja tagastab elemendi kindlal indeksil | loend.pop(1) | pop() ilma argumendita eemaldab viimase |
del loend[i] | Eemaldab elemendi või vahemiku | del loend[0:2] | Ei tagasta midagi |
clear() | Tühjendab kogu loendi | loend.clear() | Loend jääb alles, aga tühi |
remove() sobib, kui tead väärtustpop() või del() sobivad, kui tead asukohta (indeksit)clear() sobib loendi täielikuks puhastamiseks
3. Sorteerimine ja ümberpööramine
| Meetod | Kirjeldus | Näide | Märkus |
|---|---|---|---|
sort() | Sorteerib loendi (vaikimisi kasvavalt) | loend.sort() | Muudab olemasolevat loendit |
sort(reverse=True) | Sorteerib kahanevas järjekorras | loend.sort(reverse=True) | Ainult võrreldavate väärtustega töötab |
sorted(loend) | Loob uue sorteeritud koopia loendist | uus = sorted(loend) | Originaal jääb muutmata |
reverse() | Pöörab elementide järjekorra ümber | loend.reverse() | Ei sorteeri, ainult peegeldab järjekorra |
Listidega kasutamise reeglid
Mis asi on viide mälus?
Pythonis muutujad ei hoia endas mitte otse andmeid, vaid nad viitavad objektidele mälus. Kui sul on list a ja teed b = a, siis mõlemad viitavad täpselt sama mälukoha peale – see tähendab, et kui sa muudad b, siis muutub ka a.
Listide sisemised viited ja koopiad, näide:
a = [1, 2, 3]
b = a # b ei ole uus list, vaid viide samale listile
b.append(4)
print(f"a: {a}") # [1, 2, 3, 4] – a muutus ka!
print(f"b: {b}")Output:
a: [1, 2, 3, 4]
b: [1, 2, 3, 4]Miks a muutus?
Sest a ja b osutavad täpselt samale listile mälus. Kui muudame b, muudame tegelikult seda ühte ja sama objekti, mida mõlemad kasutavad.
Kuidas viitamine ja mälu töötab?
Arvuti mälu võib ette kujutada kui pikka tänavat numereeritud majadega – igal majal on unikaalne aadress. Igal mälupesal on unikaalne aadress (nt 0x001, 0x002, ..., 0xABC1 jne), mille kaudu arvuti saab andmeid kiiresti leida ja töödelda.
Kui sa kirjutad Pythonis a = [1, 2, 3], siis Python loob listi objekti mälusse, näiteks aadressile 0xABC1. Muutuja a hoiabki seda aadressi — mitte listi sisu, vaid viidet sellele mälupesale. Kui me hiljem kirjutame b = a, siis see ei kopeeri listi, vaid loob uue muutuja b, mis viitab samale aadressile 0xABC1. Nii viitavad mõlemad muutujad samale objektile.
Kui see objekt muutub (nt lisame listile uue elemendi või muudame ühte selle elementi), siis muutus on kohe näha nii akui ka b kaudu, sest nad osutavad samale kohale.
Sellist viitamise mehhanismi kasutatakse Pythonis efektiivsuse pärast. Objektide kopeerimine võtab rohkem aega ja mälu, mistõttu kasutatakse vaikimisi viiteid. Kuid see käitumine võib algajatele vahel segadust tekitada.
Kuidas teha päris koopia?
b = a.copy() # Teeb uue listi, sama sisuga
# VÕI
b = a[:] # Slicing teeb uue listi samadest elementidestMiks need töötavad?
copy()– sisseehitatud meetod, mis loob täielikult uue listi, mille sisu on sama
a[:]– viilutab kogu listi ja tagastab uue objekti mälus
Tehted ja funktsioonid listidega
Lisaks elementide lugemisele ja muutmisele võimaldab Python teha listidega erinevaid tehteid ja kontrollimisi, mis muudavad andmetega töötamise mugavaks ja loogiliseks. Nii saab listi pikendada, korrata, mõõta selle pikkust või kontrollida, kas mingi väärtus on listis olemas.
a = [1, 2]
b = [3, 4]
c = a + b # [1, 2, 3, 4] – liidab listid kokku
d = a * 3 # [1, 2, 1, 2, 1, 2] – kordab listi kolm korda
pikkus = len(a) # 2 – elementide arv listis
kas_on_2 = 2 in a # True – kas väärtus 2 leidub listisKasulikud tehted ja funktsioonid:
| Operatsioon | Näide | Tulem / Selgitus |
| Liitmine | a + b | Ühendab kaks listi (teeb uue listi) |
| Kordamine | a * 3 | Kordab listi mitu korda järjest |
| Pikkus | len(a) | Tagastab elementide arvu |
| Kuuluvus | 2 in a | Tagastab True, kui väärtus leidub listis |
| Mittekuuluvus | 5 not in b | True, kui väärtust pole listis |
Selgitus:
+ei muuda olemasolevaid liste, vaid tagastab uue
*on kasulik näiteks testides või vaikestruktuuride loomiseks
len()on oluline loendamisel ja tsüklite kontrollimisel
inabil saab kiiresti kontrollida, kas mingi väärtus on olemas – ilma, et peaks käsitsi üle kogu listi minema
List tsüklis
Listid sobivad väga hästi kasutamiseks tsüklitega, eriti for-tsüklis. Sellisel juhul käiakse listi kõik elemendid ükshaaval läbi ning iga tsüklipöörde ajal saab teha vastava elemendiga mingi tegevuse. See on üks kõige sagedamini kasutatavaid mustreid Pythonis.
Näide list tsüklis:
puuviljad = ["õun", "pirn", "ploom"]
for puuvili in puuviljad:
print(puuvili.upper())Output list tsüklis:
ÕUN
PIRN
PLOOMNäeme, et:
forelement in list: on lihtsaim ja loetavaim viis listis liikumiseks
- Igal pöördel muutub element vastavalt järgmisele väärtusele listis
print(puuvili.upper())muudab sõna suurteks tähtedeks
Kui vajad ka indeksit, kasuta enumerate():
puuviljad = ["õun", "pirn", "ploom"]
for i, puuvili in enumerate(puuviljad):
print(f"{i}: {puuvili}")Output:
0: õun
1: pirn
2: ploomNäeme, et:
enumerate()tagastab nii indeksi kui ka väärtuse
- See on soovitatavam kui
range(len(list)), kuna on loetavam ja selgem
Miks vältida for i in range(len(list)):
puuviljad = ["õun", "pirn", "ploom"]
# Vähem soovitatav viis:
for i in range(len(puuviljad)):
print(puuviljad[i])Miks see pole parim valik?
- Kood on pikem ja raskemini loetav, eriti algajatele
- Kasutatav indeks
ion ekstra muutuja, mis pole vajalik
- Kui kogemata kirjutad
range(len(puuviljad) + 1)või vale väärtuse, saadIndexError-i
Kuidas lugeda andmeid tekstifailist listi?
Sul on tekstifail nimed.txt, mille sees on selline sisu:
Mari
Jüri
Kati
ToomasLihtne koodinäide
def loe_nimed(failinimi):
# Avame faili ja loeme kõik read
with open(failinimi, "r") as f:
read = f.readlines()
# Teeme iga rea puhtaks (eemaldame tühikud ja reavahetuse)
nimed = []
for rida in read:
nimi = rida.strip()
nimed.append(nimi)
return nimed
def main():
# Kasutame funktsiooni ja prindime tulemuse
nimed = loe_nimed(failinimi="nimed.txt")
print(nimed)
if __name__ == "__main__":
main()Output:
['Mari', 'Jüri', 'Kati', 'Toomas']Näeme, et:
open(..., "r")– avab faili lugemiseks
readlines()– loeb iga rea eraldi ja teeb sellest listi
strip()– eemaldab rea lõpust\nmärgi
- Tagasi saad täiesti tavalise listi, millega saad edasi töötada
2D listid → listid listis
Pythonis võib list sisaldada teisi liste, mille tulemuseks on mitmemõõtmeline andmestruktuur. Selliseid „listide sees listi“ struktuure kasutatakse näiteks:
- Tabeli andmete hoidmiseks
- Ruudustike ja kaardistuste jaoks (nt mänguväljak)
- Ridade ja veergudega numbriliste andmete jaoks (nt statistika, CSV-failid)
- Masinõppes mitmemõõtmeliste andmete jaoks (nt pildipikslid, andmemaatriksid)
Näide ruudustik:
massiiv_ruudustiks = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]Mõtle sellele nagu Exceli tabelile:
[0][0] = 1 [0][1] = 2 [0][2] = 3
[1][0] = 4 [1][1] = 5 [1][2] = 6
[2][0] = 7 [2][1] = 8 [2][2] = 9Täiustame näide ruudustikku:
massiiv_ruudustiks = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
print(massiiv_ruudustiks)
print(massiiv_ruudustiks[0][2])
print(massiiv_ruudustiks[2][1])Output:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
3
8Näeme, et:
- 2D listi struktuur - Kui printisime terve
massiiv_ruudustiks, näeme, et Python kuvab selle kui "listi listide sees":[[1, 2, 3], [4, 5, 6], [7, 8, 9]]. Iga sisemine list[1, 2, 3]moodustab ühe "rea" meie ruudustikus.
- Topelt-indekseerimine töötab järgmiselt:
massiiv_ruudustiks[0][2]→ läheme esimesse ritta (index 0) ja sealt kolmandasse veergu (index 2) → saame väärtuse3
massiiv_ruudustiks[2][1]→ läheme kolmandasse ritta (index 2) ja sealt teise veergu (index 1) → saame väärtuse8
- Analoogia tabeliga: Mõtle sellele nagu koordinaatidele kaardil:
- Esimene number
[0]ütleb, millises reas me oleme (nagu Exceli rida)
- Teine number
[2]ütleb, millises veerus me oleme (nagu Exceli veerg)
[rida][veerg]→[0][2]tähendab "esimene rida, kolmas veerg"
- Esimene number
Praktiline ja eluline 2D listi kasutus: Tunniplaan
- Tunniplaan on ideaalne ja intuitiivne näide, kus 2D list on väga loomulik valik
- Sul on nädalapäevad ja iga päeva kohta mitu tundi (õppeainet)
Näide: Õpilase tunniplaan
esmaspaev = ["Math", "English", "History"]
teisipaev = ["Biology", "PE", "Art"]
kolmapaev = ["Physics", "Chemistry", "Music"]
# Loome 2D listi
opilase_tunniplaan = [
esmaspaev,
teisipaev,
kolmapaev
]Siin:
opilase_tunniplaan[0]= esmaspäev
opilase_tunniplaan[1][2]= teisipäev kolmas tund → "Art"
Sõnastikud
Sissejuhatus – mis asi on sõnastik?
Pythonis on sõnastik (dict) andmestruktuur, mis seob võtmed (key) väärtustega (value). See on nagu väike andmebaas sinu programmis, kus igal elemendil on nimi (võti) ja sellele vastav väärtus.
Kujutle telefoni kontaktide loendit – igal inimesel on nimi (võti) ja oma telefoninumber (väärtus). Sõnastik võimaldab kiiresti leida õige numbri, ilma kogu nimekirja läbi otsimata.
Sõnastiku loomine ja lugemine
Sõnastik luuakse loogeliste sulgude {} abil. Võtmed ja väärtused eraldatakse kooloniga, paarid omavahel komadega.
kontaktid = {
"Mari": "555-1234",
"Jüri": "555-5678",
"Kati": "555-9999"
}Kui tahame sõnastikust mingit väärtust kätte saada, saame seda teha järgnevalt:
kontaktid["Mari"]tagastab "555-1234"
- Kui võtme nime ei leita, tekib
KeyError
- Sõnastiku võtmed peavad olema muutumatud (int, str, tuple), ei sobi list või dict
Meetodid sõnastikega
| Meetod | Kirjeldus | Näide | Märkus |
|---|---|---|---|
keys() | Tagastab kõik võtmed | kontaktid.keys() | Saab muuta listiks: list(...) |
values() | Tagastab kõik väärtused | kontaktid.values() | – |
items() | Tagastab kõik (võti, väärtus) paarid | kontaktid.items() | Kasulik for tsüklis |
pop(key) | Eemaldab ja tagastab võtmega seotud väärtuse | kontaktid.pop("Kati") | Viga kui puudub |
update({...}) | Lisab või uuendab mitut paari korraga | kontaktid.update({"Leo": "123", "Mari": "777"}) | – |
clear() | Tühjendab kogu sõnastiku | kontaktid.clear() | Sõnastik jääb alles, aga tühi |
get(key, default) | Tagastab väärtuse, kui võti puudub, siis vaikeväärtuse | kontaktid.get("Anna", "Ei leitud") | Turvaline - ei anna viga KeyError viga ehk programm ei jookse kokku |
Põhitegevused sõnastikega
Väärtuse lugemine võtme abil:
print(kontaktid["Kati"]) # 555-9999Elemendi lisamine / muutmine:
kontaktid["Toomas"] = "555-0000" # Lisab uue
kontaktid["Mari"] = "555-4321" # Muudab olemasolevatElemendi kustutamine:
del kontaktid["Jüri"]
Ligipääs .get() abil:
kontaktid = {
"Mari": "555-1234",
"Jüri": "555-5678",
"Kati": "555-9999"
}
# 1. Kontrollimaks, kas võti eksisteerib
if kontaktid.get("Anna") is not None:
print("Anna number on olemas")
else:
print("Anna numbrit pole")
# 2. Vaikeväärtusega
telefon = kontaktid.get("Anna", "Pole teada")
print(f"Anna telefon: {telefon}")
# 3. Loendamises (väga kasulik!)
sõnad = ["auto", "kass", "auto", "koer", "auto"]
loendus = {}
for sõna in sõnad:
# Ilma get()-ta oleks keeruline:
# if sõna in loendus:
# loendus[sõna] += 1
# else:
# loendus[sõna] = 1
# get()-ga lihtne:
loendus[sõna] = loendus.get(sõna, 0) + 1
print(loendus) # {'auto': 3, 'kass': 1, 'koer': 1}Sõnastik tsüklis
kontaktid = {
"Mari": "555-1234",
"Jüri": "555-5678",
"Kati": "555-9999"
}
for nimi, number in kontaktid.items():
print(f"{nimi} : {number}")Näeme, et:
items()tagastab võtme ja väärtuse paarid
- Seda mustrit kasutatakse väga sageli, sest see on selge ja loetav
Kontrollid ja abifunktsioonid
| Kontroll / Tehe | Näide | Tulemus |
|---|---|---|
| Võti olemas | "Mari" in kontaktid | True |
| Võti puudub | "Peeter" not in kontaktid | True |
| Elementide arv | len(kontaktid) | 3 |
| Koopia tegemine | uus = kontaktid.copy() | Ei muuda originaali |
Sõnastiku näide
Meil on sõnastik, kus on erinevad mängijad, kes teenivad punkte. Me tahame teada palju mingi mängija punkte kokku teenib.
# Mängijad ning nende punktid
punktide_andmed = [
("Alice", 10),
("Bob", 5),
("Alice", 15), # Alice saab veel punkte
("Charlie", 8),
("Bob", 3), # Bob saab veel punkte
("Alice", 5) # Alice saab veel punkte
]
print("Punktide andmise protsess:")
for mangija, punktid in punktide_andmed:
# get() kasutamine - kui mängijat pole, alusta 0-st
praegused_punktid = mangijad_punktid.get(mangija, 0)
uued_punktid = praegused_punktid + punktid
mangijad_punktid[mangija] = uued_punktid
print(f" {mangija} sai {punktid} punkti - kokku: {uued_punktid}")
print(f"\nLõplikud tulemused: {mangijad_punktid}")Sisemised viited ja koopiad
a = {"x": 1}
b = a
b["x"] = 99
print(a) # {'x': 99}Nii nagu listide puhul → b = a viitab samale objektile mälus!
Koopia tegemiseks kasuta .copy():
b = a.copy()
b["x"] = 123
print(a) # Originaal ei muutuSõnastik failist
Faili andmed.txt sisu:
Mari:555-1234
Jüri:555-5678Lugemine sõnastikku:
def loe_kontaktid(failinimi):
d = {}
with open(failinimi) as f:
for rida in f:
osad = rida.strip().split(":")
d[osad[0]] = osad[1]
return d
def main():
kontaktid = loe_kontaktid("andmed.txt")
print(f"Kontaktid failist: {kontaktid}")
if __name__ == "__main__":
main()Väljund:
Kontaktid failist: {'Mari': '555-1234', 'Jüri': '555-5678'}Näeme, et:
- Faili lugemine rea kaupa -
with open(failinimi) as f:avab faili turvaliselt jafor rida in f:loeb iga rea eraldi. See on hea praktika, sest nagu mäletame sulgebwithstatement faili automaatselt, isegi kui tekib viga.
- Rea töötlemine samm-sammult:
rida.strip()eemaldab rea lõpust tühikud ja reavahetuse märgi (\n)
split(":")jagab rea kaheks osaks kooloni kohalt →["Mari", "555-1234"]
osad[0]on nimi ("Mari") jaosad[1]on telefoninumber ("555-1234")
- Sõnastiku ehitamine -
d[osad[0]] = osad[1]lisab sõnastikku uue võtme-väärtuse paari:- Võti (key): nimi →
"Mari"
- Väärtus (value): telefoninumber →
"555-1234"
- Võti (key): nimi →
- Tulemus: Funktsioon tagastab sõnastiku
{'Mari': '555-1234', 'Jüri': '555-5678'}, kus nimed on võtmed ja telefoninumbrid on väärtused.
- Praktiline kasutus: See meetod on väga kasulik struktureeritud andmete (CSV-sarnased failid) lugemiseks, kus iga rida sisaldab võti-väärtus paari.
Hiljem saame kiiresti otsida:
kontaktid["Mari"]annab meile Mari telefoninumbri.
if __name__ == "__main__":kontroll tagab, etmain()funktsioon käivitatakse ainult siis, kui skripti käivitatakse otse, mitte siis kui seda imporditakse teise failist.
Praktiline näide → loenda tegelasi
def loenda_tegelased(tegelased):
stat = {}
for t in tegelased:
stat[t] = stat.get(t, 0) + 1
return stat
def main():
multika_tegelased = ["Elsa", "Käsnakalle", "Elsa", "Batman", "Käsnakalle", "Elsa"]
statistika = loenda_tegelased(tegelased=multika_tegelased)
print(f"Multika tegelaste statistika: {statistika}")
if __name__ == "__main__":
main()Väga levinud muster andmete loendamisel või rühmitamisel!
zip ja .join()
Pythonis on olemas kaks väga kasulikku tööriista, kui töötame korraga mitme listi või sõnesid sisaldava listiga:
zip()– seob mitu listi omavahel element-paarideks.
.join()– ühendab stringide listi üheks suuremaks stringiks, kasutades eraldajat.
Need meetodid muudavad koodi lühemaks, loetavamaks ja aitavad vältida tarbetuid tsükleid.
zip() → mitme listi sidumine
Mis teeb zip?
- Võtab mitu listi (või muud itereeritavat) ja paneb samadel indeksitel olevad elemendid kokku tupleteks.
- Tulemus on iteraator, mitte list – kui tahad näha kõiki väärtusi, tee
list(zip(...)).
- Kui loendid on erineva pikkusega, siis zip lõpetab kõige lühema pikkuse juures.
Näide 1 → nimed ja vanused
nimed = ["Mari", "Jüri", "Kati"]
vanused = [21, 19, 23]
for nimi, vanus in zip(nimed, vanused):
print(f"{nimi} on {vanus} a.")Väljund:
Mari on 21 a.
Jüri on 19 a.
Kati on 23 a.Näide 2 → sõnastiku loomine zip abil
keys = ["eesnimi", "perenimi", "vanus"]
values = ["Mari", "Maasikas", 21]
d = dict(zip(keys, values))
print(d)Väljund:
{'eesnimi': 'Mari', 'perenimi': 'Maasikas', 'vanus': 21}Näide 3 → Sõnastiku loomine zip() abil
Kui sul on kaks listi - üks võtmetega ja teine väärtustega - saad neid kombineerida sõnastikuks kasutades dict(zip()) kombinatsiooni.
Kood 1:
# Meil on kaks eraldi listi
opilaste_nimed = ["Mari", "Jüri", "Kati", "Toomas"]
hinded = [5, 4, 5, 3]
# Loome sõnastiku, kus nimi on võti ja hinne on väärtus
hinnete_tabel = dict(zip(opilaste_nimed, hinded))
print("Hinnete tabel:")
print(hinnete_tabel)
# Saame nüüd kiiresti leida üksiku õpilase hinde
print(f"\nMari hinne: {hinnete_tabel['Mari']}")
print(f"Kati hinne: {hinnete_tabel['Kati']}")Väljund 1:
Hinnete tabel:
{'Mari': 5, 'Jüri': 4, 'Kati': 5, 'Toomas': 3}
Mari hinne: 5
Kati hinne: 5Kuidas see töötab?
zip(opilaste_nimed, hinded)seob kokku vastavad elemendid:("Mari", 5),("Jüri", 4),("Kati", 5),("Toomas", 3)
dict()teisendab need tuple'id sõnastikuks:- Esimene element tuple'is → võti
- Teine element tuple'is → väärtus
Praktiline kasutus:
# Meil on kaks eraldi listi
opilaste_nimed = ["Mari", "Jüri", "Kati", "Toomas"]
hinded = [5, 4, 5, 3]
# Loome sõnastiku, kus nimi on võti ja hinne on väärtus
hinnete_tabel = dict(zip(opilaste_nimed, hinded))
# Võime ka tsüklis läbi käia
print("\nKõigi õpilaste hinded:")
for nimi, hinne in hinnete_tabel.items():
print(f"{nimi}: {hinne}")NB! Kui listid on erineva pikkusega, siis zip() kasutab lühema listi pikkust ja pikem list lõigatakse:
nimed = ["Mari", "Jüri", "Kati"]
hinded = [5, 4, 5, 3, 2] # Pikem list
tabel = dict(zip(nimed, hinded))
print(tabel) # {'Mari': 5, 'Jüri': 4, 'Kati': 5}
# Hinded 3 ja 2 jäävad kasutamata!.join() → stringide ühendamine
Mis teeb .join()?
- On stringi meetod, mis paneb argumendiks antud stringide listi kokku üheks stringiks
- Eraldaja (separator) on meetodi eespool
Näide 1 → nimede loend komadega
nimed = ["Mari", "Jüri", "Kati"]
rida = ", ".join(nimed)
print(rida)Väljund 1:
Mari, Jüri, Kati
Näide 2 → arvude ühendamine (vajalik map(str, ...))
arvud = [1, 2, 3]
print(" + ".join(map(str, arvud)))Väljund 2:
1 + 2 + 3
Näide 3 → reavahetusega plokk
read = ["E", "T", "K", "N", "R"]
plokk = "\n".join(read)
print(plokk)Väljund 3:
E
T
K
N
RSet → Hulk
Mis asi on set (eesti keeles: hulk) ?
Set / hulk on muudetav, järjestamata ja unikaalsete elementidega andmestruktuur.
- Ei luba duplikaate
- Elementidel pole indekseid (korrastamata)
- Luuakse
{ }võiset(iterable)abil
Analoogia: peoliste külaliste register – iga nimi saab esineda ainult korra. Järjekord pole tähtis!
Näide:
def main():
a = {1, 2, 3, 3}
b = set(["õun", "pirn", "õun"])
print(a) # {1, 2, 3}
print(b) # {'õun', 'pirn'}
if __name__ == "__main__":
main()Põhiomadused
- Unikaalsus: duplikaadid eemaldatakse automaatselt
- Korrastamatus: ei saa kasutada s[0] – elementidel pole positsiooni
- Kiire kuuluvuskontroll: x in s on väga efektiivne
- Tüüpiline kasutus: duplikaatide eemaldamine, hulkade võrdlus/tehted
Duplikaadid minema:
def main():
nimed = ["Mari", "Jüri", "Mari", "Kati"]
unikaalsed = set(nimed)
print(unikaalsed) # {'Mari', 'Jüri', 'Kati'}
if __name__ == "__main__":
main()
Meetodid (kasulikumad)
| Meetod | Kirjeldus | Näide | Märkus |
|---|---|---|---|
add(x) | Lisa element hulka | s.add("Kati") | Ei lisa duplikaati |
remove(x) | Eemalda element | s.remove("Jüri") | Vis kab KeyError, kui ei leidu |
discard(x) | Eemalda, kui leidub | s.discard("Mikk") | Ei viska viga |
pop() | Võtab suvalise elemendi | elem = s.pop() | Kuna järjekorda pole |
clear() | Tühjenda hulk | s.clear() |
Näide:
def main():
s = {"Mari", "Jüri"}
s.add("Kati")
s.discard("Keegi") # OK, viga ei teki
try:
s.remove("Mikk") # KeyError, kui puudub
except KeyError:
print("Mikk puudub hulgas")
print(s)
if __name__ == "__main__":
main()
Hulgatehted (väga võimsad)
- s | t – ühend (union)
- s & t – ühisosa (intersection)
- s - t – vahe (difference)
- s ^ t – sümmeetriline vahe (ainult ühes)
Näide (trenn vs muusikakool):
def main():
trenn = {"Mari", "Jüri", "Kati", "Toomas"}
muusikakool = {"Kati", "Toomas", "Anna", "Mikk"}
print("Kõik lapsed:", trenn | muusikakool)
print("Mõlemas:", trenn & muusikakool)
print("Ainult trennis:", trenn - muusikakool)
print("Ainult muusikakoolis:", muusikakool - trenn)
print("Ainult ühes:", trenn ^ muusikakool)
if __name__ == "__main__":
main()Tuple → Muutumatu järjend
Mis asi on tuple?
Pythonis on tuple (eesti keeles: ennik) muutumatu, järjestatud kogum väärtusi. See on sarnane listiga, kuid peamine erinevus on see, et tuple'it ei saa pärast loomist muuta - see on immutable ehk muutumatu.
Tuple loomine
Tuple luuakse ümarsulgude () abil ning elemendid eraldatakse komadega.
# Tühi tuple
tuhi_tuple = ()
# Tuple numbritega
koordinaadid = (10, 20)
# Tuple erinevate andmetüüpidega
isiku_andmed = ("Mari", 25, True)
# Ühe elemendiga tuple vajab koma!
uks_element = ("ainult_see",) # Koma on vajalik!Ühe elemendiga tuple'i puhul on koma kohustuslik, muidu Python ei saa aru, et sa tahad tuple'it teha!
Tuple vs List võrdlus
| Omadus | Tuple | List |
|---|---|---|
| Muutmine | Muutmatu | Muudetav |
| Süntaks | (1, 2, 3) | [1, 2, 3] |
| Kiirus | Kiire | Aeglasem |
| Kasutus | Koordinaadid, konfiguratsioon | Andmete kogumine |
| Sõnastiku võti | Sobib | Ei sobi |
Tuple kasutamise näited
Näide 1: Koordinaadid
# 2D koordinaadid
punkt = (5, 10)
x, y = punkt # Tuple unpacking
print(f"X: {x}, Y: {y}") # X: 5, Y: 10# 3D koordinaadid
ruumi_punkt = (1, 2, 3)
x, y, z = ruumi_punkt
print(f"Punkt ruumis: ({x}, {y}, {z})")Näide 2: Funktsioon tagastab tuple
def leia_min_max(arvud):
"""Tagastab tuple koos minimaalse ja maksimaalse väärtusega"""
return (min(arvud), max(arvud))
numbrid = [5, 2, 8, 1, 9]
miinimum, maksimum = leia_min_max(numbrid)
print(f"Min: {miinimum}, Max: {maksimum}") # Min: 1, Max: 9Näide 3: Tuple sõnastiku võtmena
# Malenmäng - ruudud on koordinaatidega
male_laud = {
(1, 1): "Valge Oda",
(1, 2): "Valge Ratsu",
(8, 8): "Must Kuningas"
}
# Leiame, mis on ruudul (1, 1)
print(male_laud[(1, 1)]) # "Valge Oda"
# List ei sobiks võtmeks - annaks vea!
# male_laud[[1, 1]] = "Test" # TypeError!Näide 4: Andmete struktureerimine
# Õpilaste andmed
opilased = [
("Mari Maasikas", 20, "Informaatika"),
("Jüri Jõhvikas", 19, "Matemaatika"),
("Kati Kask", 21, "Füüsika")
]
print("Õpilaste nimekiri:")
for nimi, vanus, eriala in opilased:
print(f" {nimi} ({vanus}a) - {eriala}")Tuple põhioperatsioonid
andmed = ("Alice", 25, "Tallinn")
# Elementide lugemine (samamoodi nagu listis)
print(andmed[0]) # "Alice"
print(andmed[-1]) # "Tallinn"# Viilutamine
print(andmed[1:]) # (25, "Tallinn")# Pikkuse leidmine
print(len(andmed)) # 3# Kontroll, kas element on olemas
print("Alice" in andmed) # True
# Aga muutmine ei tööta!
# andmed[0] = "Bob"
# TypeError: 'tuple' object does not support item assignmentTuple unpacking (lahtipakkimine)
Tuple unpacking on väga kasulik Python'i omadus:
# Koordinaadid
punkt = (100, 200)
x, y = punkt
# Tuple unpacking
# Funktsioon mis tagastab mitu väärtust
def statistika(arvud):
return len(arvud), min(arvud), max(arvud), sum(arvud)
andmed = [1, 2, 3, 4, 5]
kogus, miinimum, maksimum, summa = statistika(andmed)
print(f"Elemente: {kogus}")
print(f"Min: {miinimum}, Max: {maksimum}")
print(f"Summa: {summa}")Millal kasutada tuple'it?
Kasuta tuple'it kui:
- Andmed ei muutu (koordinaadid, kuupäevad)
- Vajad sõnastiku võtit, mis koosneb mitmest osast
- Funktsioon peab tagastama mitu väärtust
- Tahad kaitsta andmeid juhuslike muudatuste eest
Ära kasuta tuple'it kui:
- Vajad andmeid muuta (lisada, eemaldada)
- Töötad dünaamilise andmekogumiga
- Vajad järjendi meetodeid nagu
append()võiremove()
Tuple zip() funktsiooniga
nimed = ["Mari", "Jüri", "Kati"]
vanused = [20, 19, 21]
# zip() loob tuple'eid
for nimi, vanus in zip(nimed, vanused):
print(f"{nimi} on {vanus} aastat vana")
# Saame ka kõik tuple'd korraga
paarid = list(zip(nimed, vanused))
print(paarid) # [('Mari', 20), ('Jüri', 19), ('Kati', 21)]
# Nagu näeme on muutuja `paarid` list, mis sisaldab tuple-t
# Teeme selle nüüd hoopis sõnastikuks
paarid = dict(paarid)
# Prindime välja ka
print(paarid) # {'Mari': 20, 'Jüri': 19, 'Kati': 21}Väljund:
Mari on 20 aastat vana
Jüri on 19 aastat vana
Kati on 21 aastat vana
[('Mari', 20), ('Jüri', 19), ('Kati', 21)]
{'Mari': 20, 'Jüri': 19, 'Kati': 21}enumerate() tupletega
Nagu teame, siis enumerate() funktsioon annab meile automaatselt indeksi iga elemendi jaoks. Eriti kasulik on see tuplite listidega töötamisel:
Näide:
# GPS koordinaatide list (tuple'ite list)
gps_punktid = [
(59.4370, 24.7536), # Tallinn
(58.3780, 26.7290), # Tartu
(58.2485, 22.4915), # Kuressaare
(59.3960, 27.3615) # Narva
]
print("GPS koordinaadid indeksitega:")
for indeks, (laius, pikkus) in enumerate(gps_punktid):
print(f"Punkt {indeks + 1}: Laius {laius}°, Pikkus {pikkus}°")Väljund:
GPS koordinaadid indeksitega:
Punkt 1: Laius 59.437°, Pikkus 24.7536°
Punkt 2: Laius 58.378°, Pikkus 26.729°
Punkt 3: Laius 58.2485°, Pikkus 22.4915°
Punkt 4: Laius 59.396°, Pikkus 27.3615°Märkused õppijatele:
enumerate(gps_punktid)tagastab tuple'i(indeks, element)iga elemendi jaoks
(laius, pikkus)on tupleunpacking→ me "pakime lahti" koordinaadi tuple'i kaheks eraldi muutujaks
Kokkuvõte
Tuple on suurepärane valik, kui vajad muutumatuid andmestruktuure. See on kiirem kui list, sobib sõnastiku võtmeks ja aitab vältida juhuslikke andmete muutmisi koodis. Kasuta tuple'it alati, kui tead, et andmed ei muutu!
Kombineeritud näide → nädalaplaan joondatud ridadena
Sageli kasutatakse zip ja .join() koos, et kuvada mitme listi andmed ühtselt vormindatud plokina.
Kood
def treeninguplaan_joondatud(paeva_nimed, km_plaan):
"""Tagastab treeninguplaani mitmerealise stringina."""
lai = max(len(p) for p in paeva_nimed) # leia pikima päeva pikkus
read = [f"{p:} : {d} km" for p, d in zip(paeva_nimed, km_plaan)]
return "\n".join(read)
def main():
paevad = ["Esmaspäev", "Teisipäev", "Kolmapäev",
"Neljapäev", "Reede", "Laupäev", "Pühapäev"]
km_per_paev = [5, 7, 0, 6, 5, 10, 12]
plaan = treeninguplaan_joondatud(paevad, km_per_paev)
print(plaan)
if __name__ == "__main__":
main()
Väljund
Esmaspäev : 5 km
Teisipäev : 7 km
Kolmapäev : 0 km
Neljapäev : 6 km
Reede : 5 km
Laupäev : 10 km
Pühapäev : 12 kmKiirvõrdlus → zip vs .join()
| Meetod | Milleks? | Näide | Märkus |
|---|---|---|---|
zip(a, b) | Kõrvutada mitut listi | for x, y in zip(xs, ys): ... | Lõikab lühima järgi |
zip(*pairs) | Transponeerida | xs, ys = zip(*pairs) | Kasulik koordinaatidega |
dict(zip()) | Ehita dict võtmetest ja väärtustest | dict(zip(keys, values)) | Võtmed peavad olema unikaalsed |
set.join() | Ühendada stringide list, eemaldab dublikaadid | ", ".join(nimed) | Kõik elemendid peavad olema str |
Tunni kokkuvõte
Selles loengus õppisime, kuidas kasutada liste ehk järjendeid Pythonis. Listid on paindlikud ja laialdaselt kasutatavad andmestruktuurid, mis võimaldavad hoida mitut väärtust ühes muutujas ning nendega mugavalt töötada.
Kokkuvõttes saime teada:
List | Tuple | Set | Dictionary | |
|---|---|---|---|---|
| Kirjapilt | [item1, item2, item3] | (item1, item2, item3) | {item1, item2, item3} | {key1 : value1 |
| Indekseeritud (elemendid on järjekorras) | ✅ | ✅ | ❌ | ✅ |
| Andmed on muudetavad | ✅ | ❌ | ❌ | ✅ |
| Duplikaadid on lubatud | ✅ | ✅ | ❌ | ❌ |
| Analoogia | Inimesed ootavad järjekorras: - inimesi võib tulla juurde ja minna ära | Isikutunnistus: - nimi ei muutu - isikukood ei muutu | Peoliste nimekiri: - kedagi ei saa olla topelt - järjekord pole oluline | Sõnaraamat: Igale sõnale on vastav seletus. |
Listid (järjendid):
- Muudetav ja järjestatud väärtuste kogum
- Luuakse nurksulgudega: [1, 2, 3]
- Igal elemendil on indeks, mis algab 0-st
- Toetab viilutamist, tsükleid, otsingut, muutmist
- Peamised meetodid:
append()
extend()
insert()
remove()
pop()
clear()
sort()
reverse()
- Viide vs koopia:
- b = a annab viite
a.copy()
a[:]teeb uue listi
- Kasutatakse sageli tsüklites, näiteks:
for element in list:
for i, element in enumerate(list):
- Saab lugeda andmeid ka failist listi
Dictionary (sõnastik):
- Muudetav ja võtme-põhine andmestruktuur
- Luuakse loogeliste sulgudega:
{"Mari": "555-1234"}
- Iga kirje koosneb võti:väärtus paarist
- Väärtusele pääseb ligi võtme abil:
dict["võti"]
- Peamised meetodid:
get(), pop(), update(), clear(), keys(), values(), items()
- Sobib andmete loendamiseks, otsimiseks ja rühmitamiseks
- Kasutatakse tihti: for key, value in
dict.items()
- Võtmed peavad olema muutumatud tüübid (str, int, tuple)
Tuple (ennik):
- Muutumatu ja järjestatud väärtuste kogum
- Luuakse ümarsulgudega:
(1, 2, 3)
- Sarnane listiga, aga ei saa pärast loomist muuta
- Kiirem kui list ja sobib sõnastiku võtmeks
- Kasulik koordinaatide, funktsioonide tagastusväärtuste ja püsivate andmete jaoks
- Toetab tuple unpacking'ut:
x, y = (10, 20)
- Ühe elemendiga tuple vajab koma:
("element",)
- Sageli kasutatav
zip()funktsiooniga, mis loob tuple'eid