Osa 5

Lisää listoista

Viime kerralla käsiteltiin lähes yksinomaan listoja, joissa alkiot ovat kokonaislukuja. Listoihin voi kuitenkin tallentaa minkä tahansa tyyppisiä arvoja. Esimerkiksi voimme tallentaa listaan merkkijonoja:

nimet = ["Maija", "Liisa", "Pekka"]
print(nimet)
nimet.append("Kalle")
print(nimet)

print("Listalla nimiä:", len(nimet))
print("Nimet aakkosjärjestyksessä:")
nimet.sort()
for nimi in nimet:
  print(nimi)
Esimerkkitulostus

['Maija', 'Liisa', 'Pekka'] ['Maija', 'Liisa', 'Pekka', 'Kalle'] Listalla nimiä: 4 Nimet aakkosjärjestyksessä: Kalle Liisa Maija Pekka

Samalla tavalla listalle voidaan tallentaa liukulukuja:

mittaukset = [-2.5, 1.1, 7.5, 14.6, 21.0, 19.2]

for mittaus in mittaukset:
    print(mittaus)

keskiarvo = sum(mittaukset) / len(mittaukset)

print("Keskiarvo:", keskiarvo)
Esimerkkitulostus

-2.5 1.1 7.5 14.6 21.0 19.2 Keskiarvo: 10.15

Sisäkkäiset listat

Listan alkiot voivat olla myös listoja:

lista = [[5, 2, 3], [4, 1], [2, 2, 5, 1]]
print(lista)
print(lista[1])
print(lista[1][0])
Esimerkkitulostus

[[5, 2, 3], [4, 1], [2, 2, 5, 1]] [4, 1] 4

Mihin voimme käyttää listoja jonka sisällä on listoja?

Voisimme esimerkiksi esittää henkilön tiedot listana, missä ensimmäisenä alkiona on henkilön nimi, toisena ikä ja kolmantena kengännumero:

["Anu", 10, 26]

Vastaavasti joukko henkilöitä on lista, joka sisältää yksittäisiä henkilöä kuvaavia listoja:

henkilot = [["Anu", 10, 26], ["Petteri", 7, 22], ["Emilia", 32, 37], ["Antti", 39, 44]]

for henkilo in henkilot:
  nimi = henkilo[0]
  ika = henkilo[1]
  kenka = henkilo[2]
  print(f"{nimi}: ikä {ika} vuotta, kengännumero {kenka}")
Esimerkkitulostus

Anu: ikä 10 vuotta, kengännumero 26 Petteri: ikä 7 vuotta, kengännumero 22 Emilia: ikä 32 vuotta, kengännumero 37 Antti: ikä 39 vuotta, kengännumero 44

Huomaa, miten for-lause käy läpi henkilöt yksitellen, eli toiston lohko-osassa muuttuja henkilo saa yksi kerrallaan arvokseen kutakin henkilöä esittävän listan.

Lista ei ole välttämättä paras Pythonin tietorakenne henkilön tietojen esittämiseen. Tutustumme pian sanakirjaan, joka on usein luontevampi tapa hoitaa vastaava tilanne.

Matriisit

Sisäkkäisten listojen avulla voidaan myös esittää matriisi eli kaksiulotteinen taulukko.

Esimerkiksi matriisi

5 1 0

voitaisiin mallintaa kaksiulotteisena listana näin:

matriisi = [[1, 2, 3], [3, 2, 1], [4, 5, 6]]

Koska matriisi on lista listoja, matriisin alkioihin viitataan käyttämällä peräkkäisiä hakasulkuja. Ensimmäinen indeksi viittaa riviin ja toinen sarakkeeseen. Niinpä esimerkiksi m[0][1] tarkoittaa ensimmäisen rivin toista alkiota (kun muistetaan, että indeksointi alkaa nollasta).

matriisi = [[1, 2, 3], [3, 2, 1], [4, 5, 6]]

print(matriisi[0][1])
matriisi[1][0] = 10
print(matriisi)
Esimerkkitulostus

2 [[1, 2, 3], [10, 2, 1], [4, 5, 6]]

Voimme käydä läpi matriisin rivit for-silmukalla. Esimerkiksi seuraava koodi tulostaa matriisin rivit allekkain:

matriisi = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

for rivi in matriisi:
    print(rivi)
Esimerkkitulostus

[1, 2, 3] [4, 5, 6] [7, 8, 9]

Seuraava koodi puolestaan tulostaa matriisin alkiot yksitellen kahden for-silmukan avulla:

matriisi = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

for rivi in matriisi:
    print("uusi rivi")
    for alkio in rivi:
        print(alkio)
Esimerkkitulostus

uusi rivi 1 2 3 uusi rivi 4 5 6 uusi rivi 7 8 9

Mikäli halutaan muuttaa matriisin sisältöä silmukan sisällä, voidaan hyödyntää range-funktiota iteroinnissa. Esimerkiksi seuraava koodi kasvattaa jokaista matriisin alkiota yhdellä:

m = [[1,2,3], [4,5,6], [7,8,9]]

for i in range(len(m)):
    for j in range(len(m[i])):
        m[i][j] += 1

print(m)
Esimerkkitulostus

[[2, 3, 4], [5, 6, 7], [8, 9, 10]]

Ulompi silmukka käy range-funktion avulla läpi arvot nollasta matriisin pituuteen (eli matriisin rivien määrään) ja sisempi silmukka jokaisen rivin alkiot nollasta rivin pituuteen.

Loading

Kaksiulotteinen taulukko pelin tietorakenteena

Matriisi sopii hyvin monien pelien tietorakenteeksi. Esim. sudokun ruudukko

5 1 1

voitaisiin esittää seuraavana matriisina:

sudoku = [
  [9, 0, 0, 0, 8, 0, 3, 0, 0],
  [0, 0, 0, 2, 5, 0, 7, 0, 0],
  [0, 2, 0, 3, 0, 0, 0, 0, 4],
  [0, 9, 4, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 7, 3, 0, 5, 6, 0],
  [7, 0, 5, 0, 6, 0, 4, 0, 0],
  [0, 0, 7, 8, 0, 3, 9, 0, 0],
  [0, 0, 1, 0, 0, 0, 0, 0, 3],
  [3, 0, 0, 0, 0, 0, 0, 0, 2]
]

Arvolla nolla siis kuvataan tilanne, missä ruutu on vielä tyhjä.

Seuraavassa vielä yksinkertainen versio sudokun tulostavasta metodista:

def tulosta(sudoku):
    for rivi in sudoku:
        for ruutu in rivi:
            if ruutu > 0:
                print(f" {ruutu}", end="")
            else:
                print(" _", end="")
        print()

tulosta(sudoku)

Tulostus näyttää seuraavalta:

 9 _ _ _ 8 _ 3 _ _
 _ _ _ 2 5 _ 7 _ _
 _ 2 _ 3 _ _ _ _ 4
 _ 9 4 _ _ _ _ _ _
 _ _ _ 7 3 _ 5 6 _
 7 _ 5 _ 6 _ 4 _ _
 _ _ 7 8 _ 3 9 _ _
 _ _ 1 _ _ _ _ _ 3
 3 _ _ _ _ _ _ _ 2

Vastaavalla tavalla on mahdollista kuvata moni tuttu peli (esim. shakki, miinaharava, laivan upotus, mastermind, ...) matriisina. Pelistä riippuu, mikä on sopiva tapa "koodata" pelin tilanne matriisiin.

Loading
Loading
Loading
Loading
Loading
:
Loading...
:
Loading...

Kirjaudu sisään nähdäksesi tehtävän.

Seuraava osa: