Järjendid 2
Eelmine nädal näitasime, kuidas kontrollida, kas element on järjendis operaatoriga in.
arvud = [1,2,3] if 1 in arvud: print("Olemas!") else: print("Element puudub!")
Nüüd kui teame, et element on olemas, siis saame tema asukoha teada käsuga index.
arvud = [1,2,3] if 1 in arvud: print("Elemendi indeks on: " + str(arvud.index(1))) else: print("Element puudub!")
Siiani oleme järjendi kirjapanekul loetlenud alati kõik tema elemendid. Paraku pole alati võimalik kõiki elemente korraga välja tuua. Appi tuleb järjendite liitmine. Tuletame kõigepealt meelde, mida see tähendas:
>>> [1, 2, 3] + [6, 4, 9] [1, 2, 3, 6, 4, 9] >>> [1] + [2] + [3] [1, 2, 3] >>> [1, 2, 3] + [4] [1, 2, 3, 4] >>> [1] + [2] + [3] + [1, 2, 3] [1, 2, 3, 1, 2, 3] >>> [1] + [] [1] >>> [] + [1] [1]
Antud juhul luuakse igakord uus järjend. On olemas ka viis append, mis lisab olemasoleva järjendi lõppu elemendi. Sarnane tegvus appendile on a += [element], mis lisab elemendi olemasolevasse järjendisse.
>>> a = [1,2,3] >>> a.append(4) [1,2,3,4]
Enesekontroll
Järjendi filtreerimine
Filtreerimiseks nimetame operatsiooni, mis moodustab mingi järjendi põhjal uue järjendi, milles sisalduvad teatud tingimustele vastavad väärtused algsest järjendist. Eemaldades element või muutes neid. Uuri ja katseta järgnevat näidet:
arvud = [1,2,3,4,5,6,7,8,9,10] for arv in arvud: if arv % 3 == 0: arvud.remove(arv) print(arvud)
Antud näites eemaldati arvud, mis jagusid 3-ga. Käsk remove eemaldab esimese antud elemendi järjendist, ehk ülejäänud sama väärtusega elemendid jäävad järjendisse. Juhul kui sooviksime esimese elemendi alles hoida, ja eemaldada järgneva, siis peaksime kasutama funktsioonid del. See funktsioon kustutab elemendi etteantud indeksil, mis antud näites oleks 2, 5 ja 8.
Enesekontroll
Järjendite kombineerimine
Küllalt sagedasti tuleb ette situatsioon, kus kahest või enamast järjendist on vaja mingi reegli põhjal panna kokku üks järjend. Kõige lihtsam juhtum on see, kus erinevate järjendite elemendid on vaja panna lihtsalt üksteise järele uude järjendisse. Nagu just nägime, saab seda teha järjendite liitmisega. Siin vaatame veidi keerulisemaid probleeme.
Järgnevas näites võtab funktsioon ühend argumendiks kaks järjendit ning tagastab uue järjendi, mis sisaldab mõlema argumentjärjendi erinevaid väärtusi ühekordselt:
def ühend(j1, j2): tulemus = [] for element in j1: if not (element in tulemus): tulemus.append(element) for element in j2: if not (element in tulemus): tulemus.append(element) return tulemus print(ühend([1, 2, 3, 2], [1, 6, 6]))
Lisaks append-ile on järjenditel veel meetodeid mis ei tagasta midagi, vaid muudavad järjendi sisu. Järgnev tabel näitab, kuidas mõjuvad erinevad meetodid järjendile [3,1,2,3,1,4], mis on salvestatud muutujasse a.
Meetodi rakendamine | Tagastusväärtus | Järjendi uus sisu | Kommentaarid |
---|---|---|---|
a.append(7) | none | [3,1,2,3,1,4,7] | lisab elemendi järjendi lõppu |
a.extend([7,8]) | none | [3,1,2,3,1,4,7,8] | lisab järjenditäie elemente järjendi lõppu |
a.insert(0,34) | none | [34,3,1,2,3,1,4] | lisab näidatud positsioonile näidatud elemendi, järgnevate elementide positsioonid nihkuvad |
a.remove(1) | none | [3,2,3,1,4] | eemaldab esimese näidatud väärtusega elemendi |
a.pop() | 4 | [3,1,2,3,1] | eemaldab viimase elemendi ja tagastab selle |
a.pop(0) | 3 | [1,2,3,1,4] | eemaldab näidatud indeksiga elemendi ja tagastab selle |
a.clear() | none | [] | eemaldab järjendist kõik elemendid |
a.sort() | none | [1,1,2,3,3,4] | sorteerib |
a.reverse() | none | [4,1,3,2,1,3] | pöörab elementide järjekorra ümber |
Nagu näha, tagastab enamik neist meetoditest selle veidra väärtuse None, mis tähendab sisuliselt väärtuse puudumist. Teisti öeldes, neid meetodeid käivitatakse vaid kõrvalefekti pärast. Antud juhul on kõrvalefektiks järjendi muutmine.
Enesekontroll
Muudetavate andmetüüpide omapärad
Järjendi muutmisel või täiendamisel (nii append-i kui a[i] = x puhul) tuleb arvestada ühe omapäraga, mis tuleb ilmsiks siis, kui sama järjend on omistatud mitmele muutujale. Uuri järgnevat näidet ning ennusta, mis antakse selle programmi käivitamisel väljundiks:
a = [1, 2, 3] b = a b.append(4) print(a)
Nagu nägid, ilmus ekraanile [1, 2, 3, 4], ehkki programmist ei paista, et kusagil oleks järjendisse a lisatud arv 4. Selle omapära põhjus peitub real b = a, mis mitte ei kopeeri muutuja a väärtust muutujasse b, vaid hoopis paneb muutuja b viitama samale järjendile. Teisisõnu, b on sama järjendi alternatiivne nimi (ingl alias). Seetõttu, kui järjendit muuta kasutades nime b, on muudatus näha ka nime a kaudu (ja vastupidi).
Seda omapära võib vahepeal ka enda kasuks kasutada. Kui aga soovid parameetrina saadud järjendit arvutuse käigus muuta nii, et funktsioonist väljaspool muutusi näha poleks, siis tuleks teha saadud järjendist koopia ning muudatused teha vaid koopiale. Koopia tegemiseks saab kasutada viilutamise süntaksit, jättes kirjutamata nii vasaku kui parema indeksi. Lisaks saab kasutada meetodit copy:
a = [1, 2, 3] b = a[:] b.append(4) c = a.copy() c.append(4) print(a) # a väärtus on endine
Märkus Kas selline situatsioon, et erinevad muutujad viitavad samale objektile, on võimalik ainult järjendite korral? Tehniliselt võttes ei – muutujad ja harilik (=-ga) omistamine toimivad alati samamoodi hoolimata andmetüübist.
Kõik Pythoni väärtused on programmi käimise ajal esitatud mingite objektidena, mis asuvad kusagil arvuti mälus. Kui käivitatakse lause x = 7, siis luuakse mälus objekt, mis tähistab arvu 7 ja muutujasse x salvestatakse tegelikult ainult viide sellele objektile. Kui me järgmisena käivitame lause y = x, siis muutujasse y salvestatakse sama viit, mis on muutujas x, aga uut täisarvu objekti ei looda. Seega nüüd viitavad muutujad x ja y samale objektile.
Järjend, mis sisaldab järjendit
Nagu varasemalt õppisime, siis järjendis saavad olla erinevat tüüpi andmeid. See tähendab, et järjendi elemendid võivad olla veel teised elemendid. Selliselt saab koostada maatrikseid, mida saab kasutada näiteks erinevate matemaatiliste ülesannete lahendamiseks.
Näiteks need kaks järjendit on täpselt sama sisuga.
järjend = [[1,2,3], [1,2,3], [1,2,3]] maatriks = [[1,2,3], [1,2,3], [1,2,3]]
Järjendite muutmise video
https://panopto.ut.ee/Panopto/Pages/Viewer.aspx?id=86176b80-ab58-483e-afd8-ac5c00eff523
Enesekontroll
Failist lugemine kahemõõtmelisse järjendisse
Järjendi peatükis tõime näite failist, kus oli ühel real tühikuga eraldatult päeva miinimum- ja maksimumtemperatuurid:
Näiteks, kui meil on failis arvud.txt ühel real päeva miinimum- ja maksimumtemperatuurid:
5.0 15.2 6.2 12.4 7.2 12.3 5.1 10.5 4.8 9.5 4.5 10.8 6.2 12.5
Siis saame väljastada ekraanile ühe rea elemendid:
fail = open("arvud.txt") for rida in fail: osad = rida.split() print(float(osad[1]), float(osad[0])) fail.close()
Seda programmi tahaks nüüd täiendada selliselt, et temperatuurid loetakse failist järjendisse, kus iga element on omakorda järjend vastava päeva miinimum- ja maksimumtemperatuuriga. Selleks loome tühja järjendi temperatuurid
ja tsüklis omakorda ajutise järjendi ühe_päeva_temperatuurid
, kuhu saame vastava päeva miinimum- ja maksimumtemperatuurid lisada:
temperatuurid = [] fail = open("arvud.txt") for rida in fail: ühe_päeva_temperatuurid = [] osad = rida.split() ühe_päeva_temperatuurid.append(float(osad[1])) ühe_päeva_temperatuurid.append(float(osad[0])) temperatuurid.append(ühe_päeva_temperatuurid) fail.close() print(temperatuurid)
Katseta, mis selle programmiga ekraanile väljastatakse.
Ennikud
Ennik (ingl tuple) on Pythoni andmetüüp, mis on järjendiga väga sarnane. Kõige suurem vahe enniku ja järjendi vahel on see, et järjendeid saab muuta, ennikuid aga mitte. Enniku elemendid kirjutatakse ümarsulgude vahele, aga nende indekseerimiseks kasutatakse siiski nurksulge:
punkt = (3, 8) # kahe elemendiga ennik e paar print("Punkti x-koordinaat on:", punkt[0]) print("Punkti y-koordinaat on:", punkt[1]) andmed = ("Peeter", "Paun", 1967) # kolme elemendiga ennik e kolmik print("Eesnimi:", andmed[0]) print("Perenimi:", andmed[1]) print("Sünniaasta:", andmed[2])
Tegelikult saaksime siin ennikute asemel kasutada ka järjendeid, aga hea tava on kasutada järjendeid vaid neil juhtudel, kus kogumi elemendid on kõik ühte tüüpi. Kui meil on mingi kindel komplekt elemente, mida me tahame koos käsitleda, ja mis võivad olla erinevat tüüpi, siis on parem paigutada need ennikusse.
Märkus Mingit 3-elemendilist kogumit nimetatakse tavaliselt kolmikuks, 4-elemendilist nelikuks jne. Enniku nimi on tulnud selle skeemi üldistamisest: n-elemendilist kogumit nimetatakse ennikuks.
Enniku video
https://panopto.ut.ee/Panopto/Pages/Viewer.aspx?id=9796a99f-7e9f-4f94-906a-ac5b008036c7
Kasutatud allikad: