Andmestruktuuride kordamine
Seni oleme tutvunud andmestruktuuridest järjendite, kahemõõtmeliste järjendite, enniku, sõnastiku ja hulgaga. Siin peatükis vaatame veel erinevaid näidisülesandeid ja nende lahendusi.
Alltoodud tabelis on võrdlevalt väljatoodud Pythoni põhiliste andmestruktuuride omadused. Tegelikult on see info eelnevates materjalides juba olemas. Siin on see lihtsalt kompaktsemalt esitatud.
Järjend (ingl list) |
Ennik (ingl tuple) |
Hulk (ingl set) |
Sõnastik (ingl dict) | |
Järjestus |
Unikaalsed indeksid, kindel järjestus |
Unikaalsed indeksid, kindel järjestus |
Ei ole indekseid, kindel järjestus puudub |
Unikaalsed võtmed, kindel järjestus (alates versioonist 3.7) |
Näited |
järjend = [] järjend = list() järjend = [7] järjend = ['999', 777] |
ennik = () ennik = tuple() ennik = (42,) ennik = ('PAII', 1011) |
hulk = set() hulk = {4} hulk = {'s', 'e', 't', 2} |
sõnastik = {} sõnastik = dict() sõnastik = {'üks': 1} sõnastik = {'四': 4, '五': 5, 4: 4} |
Elemendi lisamine |
järjend += [element] järjend.append(element) |
Mittemuteeritav, elemente ei saa lisada |
hulk.add(element) |
sõnastik[võti] = väärtus |
Elemendi muutmine |
järjend[indeks] = väärtus |
Mittemuteeritav, elemente ei saa muuta |
hulk.remove(element) hulk.add(element) |
sõnastik[võti] = väärtus |
Teisendamine |
Näiteks hulgast järjendiks list({3, 4}) → [3, 4] |
Näiteks järjendist ennikuks tuple([3, 4]) → (3, 4) |
Näiteks järjendist hulgaks set([3, 4]) → {3, 4} |
Näiteks paaride järjendist sõnastikuks dict([('Aare', 49), ('Malle', 46)]) → {'Aare': 49, 'Malle': 46} |
Elementide korduvus |
Võib olla korduvaid elemente |
Võib olla korduvaid elemente |
Korduvaid elemente ei ole |
Korduvaid võtmeid ei ole |
Sõnastike näidisülesanne 1. Kandidaadid
Antud on kahe valimisjaoskonna kandidaatide nimed ja nende kogutud häälte arvud Pythoni sõnastikes. Kui keegi sai 0 häält, siis teda sõnastikus ei ole. Kirjutada programm, mis liidab valimisjaoskondade tulemused kokku.
v1 = {'Kask': 151, 'Tamm': 23, 'Haab': 34} v2 = {'Mänd': 15, 'Kuusk': 221, 'Kask': 28, 'Tamm': 34} v = kokku(v1, v2)
Tulemus:
{'Kask': 179, 'Tamm': 57, 'Haab': 34, 'Mänd': 15, 'Kuusk': 221
Näidislahendus (versioon 1)
def kokku1(d1, d2): d = {} for nimi, hääli in d1.items(): d[nimi] = d2.get(nimi, 0) + hääli for nimi, hääli in d2.items(): if nimi not in d1: d[nimi] = hääli return d v1 = {'Kask': 151, 'Tamm': 23, 'Haab': 34} v2 = {'Mänd': 15, 'Kuusk': 221, 'Kask': 28, 'Tamm': 34} print(kokku1(v1, v2))
Näidislahendus (versioon 2)
def kokku2(d1, d2): d = d1.copy() for nimi, hääli in d2.items(): d[nimi] = d.get(nimi, 0) + hääli return d v1 = {'Kask': 151, 'Tamm': 23, 'Haab': 34} v2 = {'Mänd': 15, 'Kuusk': 221, 'Kask': 28, 'Tamm': 34} v = kokku2(v1, v2) print(v)
Sõnastike näidisülesanne 2. Korduvad elemendid
Leida, mitu väärtust esineb sõnastikus rohkem kui üks kord.
d = {'R': 1, 'G': 2, 'B': 2, 'Y': 1, 'P': 3, 'A': 1} korduvaid = korduvate_arv(d) print(korduvaid)
Tulemus: 2
Näidislahendus
def korduvate_arv(d): arv = 0 väärtused = list(d.values()) unikaalsed = set(d.values()) for väärtus in unikaalsed: if väärtused.count(väärtus) > 1: arv = arv + 1 return arv d = {'R': 1, 'G': 2, 'B': 2, 'Y': 1, 'P': 3, 'A': 1} korduvaid = korduvate_arv(d) print(korduvaid)
Sõnastike ja hulga näidisülesanne 3. Korduvad elemendid
Õpilaste aastahinded matemaatikas on koondatud sõnastikku, kus võtmeks on õpilase nimi ja väärtuseks on aastahinne. Koostada uus sõnastik, kus võtmeks on hinne ja väärtuseks hulk õpilastest, kes selle hinde said.
d = {'Karl': 3, 'Robin': 4, 'Hugo': 5, 'Mia': 5, 'Eva': 3, 'Mary': 4} dt = tagurpidi_sõnastik(d) print(dt)
Tulemus: {3: {'Karl', 'Eva'}, 4: {'Robin', 'Mary'}, 5: {'Hugo', 'Mia'}}
Näidislahendus
def tagurpidi_sõnastik(d): uus = {} for nimi, hinne in d.items(): õpilased = uus.get(hinne, set()) õpilased.add(nimi) uus[hinne] = õpilased return uus d = {'Karl': 3, 'Robin': 4, 'Hugo': 5, 'Mia': 5, 'Eva': 3, 'Mary': 4} dt = tagurpidi_sõnastik(d) print(dt)
Näidisülesannete 1, 2 ja 3 selgitav video:
https://panopto.ut.ee/Panopto/Pages/Viewer.aspx?id=a36f9f5f-b394-4e16-9c86-ac6b007c5bdf
Sõnastike näidisülesanne 4. Raamatud
Antud on sõnastik raamatutega.
raamatud = {1: {'pealkiri': 'Legoist', 'autor': 'Contra', 'ilmumisaasta': 2019, 'kirjastus': 'Mina Ise' }, 2: {'pealkiri': 'Hea une teejuht', 'autor': 'Kene Vernik', 'ilmumisaasta': 2019, 'kirjastus': 'Pilgrim' }, 3: {...} ... }
On vaja teha andmetest väljavõtted.
- Iga autori kohta pealkirjade nimekiri.
- Iga kirjastuse kohta autorite nimekiri (autorid ühekordselt).
- Iga ilmumisaasta kohta kolmikute (autor, pealkiri, kirjastus)
nimekiri.
- Iga autori kohta kirjastuste nimekiri hulgana.
- Kahe etteantud autori ühised kirjastused.
4. Näidisülesande lahendus
# Iga autori kohta pealkirjade nimekiri def autorid(raamatud): d = {} for raamat in raamatud.values(): raamatud = d.get(raamat['autor'], []) raamatud.append(raamat['pealkiri']) d[raamat['autor']] = raamatud return d # Iga kirjastuse kohta autorite nimekiri (autorid ühekordselt) def kirjastused(raamatud): d = {} for raamat in raamatud.values(): autorid = d.get(raamat['kirjastus'], []) if raamat['autor'] not in autorid: autorid.append(raamat['autor']) d[raamat['kirjastus']] = autorid return d # Iga ilmumisaasta kohta kolmikute (autor, pealkiri, kirjastus) nimekiri def ilmumisaastad(raamatud): d = {} for r in raamatud.values(): teosed = d.get(r['ilmumisaasta'], []) kolmik = (r['autor'], r['pealkiri'], r['kirjastus']) teosed.append(kolmik) d[r['ilmumisaasta']] = teosed return d # Iga autori kohta kirjastuste nimekiri hulgana Iga autori kohta kirjastuste nimekiri hulgana def autorite_kirjastused(raamatud): d = {} for raamat in raamatud.values(): kirjastused = d.get(raamat['autor'], set()) kirjastused.add(raamat['kirjastus']) d[raamat['autor']] = kirjastused return d # Kahe etteantud autori ühised kirjastused def ühised_kirjastused(autor1, autor2, ak): kirjastused = ak[autor1] & ak[autor2] return kirjastused ak = autorite_kirjastused(raamatud) aük = ühised_kirjastused('Liis Velsker', 'Eia Uus', ak) print(aük)
Näidisülesande 4 selgitav video:
https://panopto.ut.ee/Panopto/Pages/Viewer.aspx?id=614a06f2-ad8b-44d9-8d58-ac6b00b8f223
Failist lugemine sõnastikku
Vaatame ka näidet, kuidas lugeda failist sõnastikku. Olgu meil fail sonastik.txt, mis on eesti-inglise sõnastik, kus eestikeelne ja ingliskeelne sõna on eraldatud semikooloniga. Näiteks võib faili sonastik.txt sisu olla selline:
kass;cat koer;dog hiir;mouse
Kuidas saaksime selle sisu lugeda Pythoni programmi selliselt, et võtmeteks oleks eestikeelsed sõnad ja väärtusteks vastavad ingliskeelsed sõnad? Selleks tuleks fail rida haavad programmi lugeda ning seejärel read teha semikooloni pealt tükkideks ning lisada vastavalt sõnastikku. Näiteks saab seda teha nii:
sõnastik = {} fail = open("sonastik.txt", encoding="UTF-8") for rida in fail: osad = rida.strip().split(";") sõnastik[osad[0]] = osad[1] fail.close() print(sõnastik)
Selleks, et programmi paremini struktureerida, võib seda teha ka eraldi funktsioonis, mis saab argumendiks failinime ja tagastab sõnastiku:
def loe_failist(failinimi): sõnastik = {} fail = open(failinimi, encoding="UTF-8") for rida in fail: osad = rida.strip().split(";") sõnastik[osad[0]] = osad[1] fail.close() return sõnastik print(loe_failist("sonastik.txt"))
Failist lugemine sõnastikku, kus väärtuseks on järjend
Mis saab aga siis, kui failis on rohkem andmeid ja tahaks sõnastiku väärtuseks lisada järjendi? Oletame, et meil on failis õppeainete nimi ja erinevate õppeainete hinded eraldatud komadega ja sooviksime need lugeda sõnastikku, mille võtmeks on õppeaine ja väärtuseks vastava õppeaine hindeded. Selleks tuleks käituda samamoodi nagu eelmise näite puhul, aga kõik hinded tuleks teisendada täisarvudeks ja lisada järjendisse ning siis alles lisada sõnastikku.
Olgu meil fail hinded.txt:
matemaatika,4,5,4 eesti keel,3,4 inglise keel,5,5,5
Funktsioon loe_failist, mis loeks need hinded sõnastikku selliselt, et võtmeks on aine ja väärtuseks hinnete järjend ning tagastaks selle sõnatiku, näeks välja selline:
def loe_failist(failinimi): sõnastik = {} fail = open(failinimi, encoding="UTF-8") for rida in fail: osad = rida.strip().split(",") hinded = [] for el in osad[1:]: hinded.append(int(el)) sõnastik[osad[0]] = hinded fail.close() return sõnastik print(loe_failist("hinded.txt"))