< eelmine | 12. nädala sisukord | järgmine > |
12.9 REKURSIIVSED ANDMESTRUKTUURID
JÄRJENDID JÄRJENDITE SEES
See, et järjendi elemendiks võib olla järjend, ei ole meile uudiseks - oleme ju pikalt tegutsenud kahemõõtmeliste järjenditega. Põhiliselt olid meil analüüsimisel tabelid (maatriksid), mille igas reas oli võrdselt elemente. Tegelikult võivad read olla erineva pikkusega. Mitmed tollased programmid töötaksid ka selliste kahemõõtmeliste järjenditega. Igatahes aga oli meil alati kaks mõõdet - "välimine" järjend koosnes järjenditest. "Sisemistes" järjendites olid aga juba nt arvud. Kui sisemised järjendid oleksid olnud veel omakorda järjendid - oleks tegemist kolmemõõtmelise järjendiga.
Nüüd aga võtame vaatluse alla sellised andmestuktuurid, kus me mõõtmete arvu ei tea. Näiteks olgu meil järjend, mille iga element on täisarv või järjend, milles omakorda on iga element täisarv või järjend, milles omakorda on iga element täisarv või järjend, milles omakorda on iga element täisarv või järjend ...
Näiteks on mõned sellised:
[1, [2], [3, 4]] [1, [2, [[3, 4], [5, 6]]], [7, 8, 9]] [1, 2, 3, 4]
Sääraste andmestruktuuride käsitlemisel on rekursioon suureks abiks. Järgmine funktsioon tagastab kõigi argumendina antud struktuuris oleva arvude summa olenemata sellest, kui sügaval oleva listi sees see arv asub.
def summa(struktuur): tulemus = 0 for element in struktuur: if isinstance(element, list): tulemus += summa(element) else: tulemus += element return tulemus print(summa([1, [2], [3, 4]])) print(summa([1, [2, [[3, 4], [5, 6]]], [7, 8, 9]])) print(summa([1, 2, 3, 4]))
Funktsioon isinstance
abil kontrollitakse, kas vaatluse all olev element on järjend (list). Kui on, siis peame rekursiivselt sügavamale minema. Kui pole, saame liita.
FAILIDE JA KAUSTADE KUVAMINE
Rekursiivse struktuuri moodustavad ka näiteks kaustad ja failid kõvakettal vm. Kaustas võivad olla nii failid, kui kaustad, milles võivad olla failid või kaustad, milles omakorda võivad olla failid või kaustad ...
Simuleerime kaustade ja failidega tegutsemist järgmise ülesandega.
Koostada rekursiivne funktsioon, mis läbib rekursiivselt argumendiks antud mitmemõõtmelise järjendi kõik elemendid. Kui järjendi element on järjend, siis trükitakse ekraanile sõna „Kaust“ ja järjekorranumber (alustades 1-st). Vastasel juhul sõna „Fail:“ ja selle järel failinimi. Kusjuures väljatrükil peab kasutama taanet, et kaustade sisust oleks võimalik visuaalselt aru saada.
Täpsustused. Funktsioon saab argumentidena ette järjendi ja taande, mille vaikeväärtus võib tühi sõne olla.
Näiteks järjendi
[["Fail11"], ["Fail21"], [["Fail311"], "Fail31", "Fail32", "Fail33"], "Fail1", "Fail2"]
korral on võimalik väljund
Kaust 1: Fail: Fail11 Kaust 2: Fail: Fail21 Kaust 3: Kaust 1: Fail: Fail311 Fail: Fail31 Fail: Fail32 Fail: Fail33 Fail: Fail1 Fail: Fail2
Taandena võib kasutada tabulaatorit – "\t". Seda, kas element on järjend, saame, nagu juba eespool mainitud, teada funktsiooni isinstance
abil.
Päris kaustade ja failidega tegutsemiseks on Pythonis olema spetsiaalsed vahendid. Näiteks kaustas olevate failide ja kaustade nimed saab järjendina os.listdir abil. Seda, kas on tegemist kaustaga (ja mitte failiga), saab kontrollida os.path.isdir abil. Olge aga päris kaustade ja failidega tegutsemisega ettevaatlik, olemas on ka funktsioonid kustutamiseks ...
< eelmine | 12. nädala sisukord | järgmine > |