Arvutiteaduse instituut
  1. Kursused
  2. 2016/17 kevad
  3. Programmeerimise alused II (LTAT.TK.001)
EN
Logi sisse

Programmeerimise alused II 2016/17 kevad

  • Kursuse info
  • 1. Kahemõõtmeline järjend
  • 2. Kahekordne tsükkel
  • 3. Andmestruktuurid
  • 4. Viitamine ja muteerimine

4.1 Viitamine 4.2 Muteerimine 4.3 Järjendi muteerimine 4.4 Funktsioon ja muteerimine 4.5 Kordamine 4.6 Silmaring: Objekt-orienteeritud programmeerimine

  • 5. Testimine ja silumine. Rekursioon
  • 6. Rekursioon II
  • 7. Projekt?
  • Korraldajad
IV OSA sisukord

4.3 JÄRJENDI MUTEERIMINE

Pythonis on järjendid muteeritavad, mis tähendab, et järjend võib programmi töö jooksul sisaldada erinevaid väärtusi. Näiteks

järjend = [1, 2, 6, -7]
print(id(järjend))

järjend[1] = 4
print(id(järjend))

järjend.append(45)
print(id(järjend))

järjend += [9]
print(id(järjend))

järjend = järjend + [8]
print(id(järjend))

Väljastatakse arvud

20139104
20139104
20139104
20139104
9977904

Näeme, et kuni viimase muutuseni on tegemist sama järjendiobjekti muutmisega, viimane aga tekitab uue.

Mis juhtub, kui enne muteerimist on ka teine muutuja seotud?

Näeme, et tõesti on tegemist täpselt sama objektiga. Vahel on aga vaja, et koopiad oleksid sõltumatud.

Sõltumatu koopia

Kui tahame sõltumatut koopiat, siis saame kasutada viilutamist

c = a[:]

või funktsiooni copy

d = a.copy()

See sõltumatus on siiski vaid välimisel tasemel ja toimib kenasti, kui järjend koosneb mittemuteeritavatest suurustest. Kui aga järjend koosneb muteeritavatest elementidest, näiteks järjenditest, siis sügavamal tasemel jääb sõltuvus alles. See tuleb sellest, et viidad välimistele elementidele on samad.

tabel = [[1, 2, 3], [4, 5, 6]]
tabel2 = tabel.copy() # või tabel2 = tabel[:]
print(id(tabel[0]))
print(id(tabel2[0]))

Väljastatakse

18374408
18374408

Kui nüüd muudame näiteks ühel kahemõõtmelisel järjendil ülal vasakul asetsevat elementi, siis muutub see ka teisel.

tabel = [[1, 2, 3], [4, 5, 6]]
tabel2 = tabel.copy() # või tabel2 = tabel[:]
# print(id(tabel[0]))
# print(id(tabel2[0]))
tabel2[0][0] = 12
print(tabel)
print(tabel2)

Väljastatakse

[[12, 2, 3], [4, 5, 6]]
[[12, 2, 3], [4, 5, 6]]

Samas välimisel tasemel on sõltumatus ja nii saame elementjärjendeid eemaldada, uusi elementjärjendeid juurde panna. Saame ka elementjärjendeid uutega asendada.

tabel = [[1, 2, 3], [4, 5, 6]]
tabel2 = tabel.copy() # või tabel2 = tabel[:]
tabel[1] = [23, 45, 67]
print(id(tabel[1]))
print(id(tabel2[1]))
print(tabel)
print(tabel2)

Väljastatakse

11943984
12598368
[[1, 2, 3], [23, 45, 67]]
[[1, 2, 3], [4, 5, 6]]

Kuna nüüd on kummaski järjendis indeksiga 1 elementjärjent erinev (erineva viidaga), siis saame ka selles elementjärjendis ka üksikuid elemente sõltumatult muuta.

tabel = [[1, 2, 3], [4, 5, 6]]
tabel2 = tabel.copy() # või tabel2 = tabel[:]
tabel[1] = [23, 45, 67]
tabel[1][1] = -4
print(tabel)
print(tabel2)

Kui tahta täielikult sõltumatut koopiat, siis saab kasutada funktsiooni deep.copy moodulist copy.

from copy import deepcopy
tabel3 = [[1, 2, 3], [4, 5, 6]]
tabel4 = deepcopy(tabel3)
tabel3[0].append(7)
print(tabel3)
print(tabel4)

Järjendite "korrutamine"

Pythonis on mitmeid võimalusi, mida teistes programmeerimiskeeltes ei pruugi olla. Näiteks tehtemärk * toimib ka sõnede, järjendite ja ennikute korral.

print([1, 3, 4] * 3)
print("Elagu! " * 4)
print((1, 4, 6) * 2)

Kordaja võib olla ka ees, nt 4 * "Elagu".

Proovime nüüd *-märgi abil saada 3*4-maatriksi, mis sisaldab ainult nulle. Kuna [0] * 4 annab meile järjendi, milles on 4 nulli, siis [[0] * 4] * 3 toimel soovitu saamegi.

maatriks = [[0] * 4] * 3
print(maatriks)

Väljastatakse maatriks

[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

Selline maatriks võib olla heaks aluseks mingite andmete jaoks, mida siis järjest õigetele kohtadele pannakse.

Proovime näiteks kohale (0, 0) panna arvu 1.

maatriks = [[0] * 4] * 3
maatriks[0][0] = 1
print(maatriks)

Väljastatakse maatriks

[[1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0]]

Näeme, et muutus toimus kõikides ridades. Seda sellepärast, et *-märgi toimel kopeeritakse vastav arv korda viitasid. Kuna need viitavad samale järjendile, siis muidugi muutuvad kõik korraga.

Kui tahta ikkagi sõltumatuid ridu saada, siis võime kirjutada järgmise funktsiooni.

def nullmaatriks(ridu, veerge):
    maatriks = []
    for i in range(ridu):
          maatriks.append([0] * veerge)
    return maatriks

maatr = nullmaatriks(3, 4)
maatr[0][0] = 1
print(maatr)

IV OSA sisukord
  • Arvutiteaduse instituut
  • Loodus- ja täppisteaduste valdkond
  • Tartu Ülikool
Tehniliste probleemide või küsimuste korral kirjuta:

Kursuse sisu ja korralduslike küsimustega pöörduge kursuse korraldajate poole.
Õppematerjalide varalised autoriõigused kuuluvad Tartu Ülikoolile. Õppematerjalide kasutamine on lubatud autoriõiguse seaduses ettenähtud teose vaba kasutamise eesmärkidel ja tingimustel. Õppematerjalide kasutamisel on kasutaja kohustatud viitama õppematerjalide autorile.
Õppematerjalide kasutamine muudel eesmärkidel on lubatud ainult Tartu Ülikooli eelneval kirjalikul nõusolekul.
Tartu Ülikooli arvutiteaduse instituudi kursuste läbiviimist toetavad järgmised programmid:
euroopa sotsiaalfondi logo