Kirjautuminen

Haku

Tehtävät

Oppaat: Python-ohjelmointi: Osa 10 - Tietorakenteet

  1. Osa 1 - Ensimmäinen ohjelma
  2. Osa 2 - Tiedon käsittely
  3. Osa 3 - Ehtorakenteet
  4. Osa 4 - Toistorakenteet
  5. Osa 5 - Listojen käsittely
  6. Osa 6 - Merkkijonot
  7. Osa 7 - Omat funktiot
  8. Osa 8 - Tiedostot ja virheet
  9. Osa 9 - Standardikirjasto
  10. Osa 10 - Tietorakenteet
  11. Osa 11 - Alkeita edemmäs
  12. Osa 12 - Yhteenveto
  13. Liite 1 - Asennus ja käyttö

Kirjoittaja: Antti Laaksonen (2015).

Tähän mennessä listan alkiot ovat olleet vain lukuja ja merkkijonoja, mutta listan alkiot voivat olla myös listoja. Tämän ansiosta listan alkiot voivat sisältää monta erillistä tietoa tai lista voi esimerkiksi esittää kaksiulotteista ruudukkoa. Edelleen listan sisällä voi olla monta sisäkkäistä tasoa listoja, mikä mahdollistaa monimutkaisten tietorakenteiden toteutuksen.

Tämä opas esittelee sisäkkäisten listojen käyttöä esimerkkien avulla. Lisäksi oppaan lopussa tulee tutuksi Python-kielen tietorakenne sanakirja, josta voi hakea kätevästi tietoa hakuavaimen avulla.

Lista listassa

Seuraavassa ohjelmassa listan sisällä on kolme alilistaa:

listat = [
    [1, 2, 3, 4],
    [5, 6, 7, 8, 9, 10],
    [11, 12]
]

print("Listoja yhteensä:", len(listat))
print("1. lista:", listat[0])
print("2. lista:", listat[1])
print("3. lista:", listat[2])
print("1. listan 2. luku:", listat[0][1])
print("2. listan 4. luku:", listat[1][3])
print("3. listan 1. luku:", listat[2][0])

print("Kaikki luvut:")
for lista in listat:
    for luku in lista:
        print(luku, end = " ")
    print()

Ohjelman tulostus on seuraava:

Listoja yhteensä: 3
1. lista: [1, 2, 3, 4]
2. lista: [5, 6, 7, 8, 9, 10]
3. lista: [11, 12]
1. listan 2. luku: 2
2. listan 4. luku: 8
3. listan 1. luku: 11
Kaikki luvut:
1 2 3 4
5 6 7 8 9 10
11 12

Listan listat alkiot ovat alilistoja, joiden alkiot ovat lukuja. Merkintä listat[a] viittaa tiettyyn alilistaan, ja merkintä listat[a][b] viittaa tietyn alilistan tiettyyn lukuun. Edelleen alilistojen sisällä voisi olla alialilistoja jne., jolloin hakasulkuja ja sisäkkäisiä for-silmukoita tulisi lisää.

Esimerkki: Tuloslista

Seuraava ohjelma tulostaa pelin tuloslistan:

lista = [
    ["Uolevi", 100],
    ["Henrikki", 80],
    ["Antti", 30],
    ["Nimetön", 0],
    ["Nimetön", 0]
]

for tulos in lista:
    print("Nimi:", tulos[0])
    print("Pisteet:", tulos[1])

Ohjelman tulostus on seuraava:

Nimi: Uolevi
Pisteet: 100
Nimi: Henrikki
Pisteet: 80
Nimi: Antti
Pisteet: 30
Nimi: Nimetön
Pisteet: 0
Nimi: Nimetön
Pisteet: 0

Tässä listan alkiot muodostuvat kahdesta osasta: ensin tulee pelaajan nimi, sitten hänen pistemääränsä.

Esimerkki: Labyrintti

Seuraava ohjelma piirtää labyrintin listan perusteella:

kartta = [
    [1, 1, 1, 1, 1, 1],
    [1, 2, 1, 1, 0, 0],
    [1, 0, 0, 0, 0, 1],
    [1, 0, 1, 1, 0, 1],
    [1, 0, 0, 0, 0, 1],
    [1, 1, 1, 1, 1, 1]
]
merkit = " #@"
for rivi in kartta:
    for ruutu in rivi:
        print(merkit[ruutu], end = "")
    print()

Ohjelman tulostus on seuraava:

######
#@##
#    #
# ## #
#    #
######

Listassa kartta kerrotaan jokaisesta labyrintin ruudusta, onko se lattiaa (0), seinää (1) vai onko siinä pelaaja (2). Merkkijonossa merkit lukee, mitkä merkit vastaavat erilaisia labyrintin ruutuja.

Seuraavassa ohjelmassa pelaaja voi liikkua labyrintissa:

kartta = [
    [1, 1, 1, 1, 1, 1],
    [1, 2, 1, 1, 0, 0],
    [1, 0, 0, 0, 0, 1],
    [1, 0, 1, 1, 0, 1],
    [1, 0, 0, 0, 0, 1],
    [1, 1, 1, 1, 1, 1]
]
omay = 1
omax = 1
merkit = " #@"
while True:
    for rivi in kartta:
        for ruutu in rivi:
            print(merkit[ruutu], end = "")
        print()
    if omay == 1 and omax == 5:
        print("Pääsit maaliin!")
        break
    suunta = input("Suunta (y/a/v/o): ")
    uusix = omax
    uusiy = omay
    if suunta == "y":
        uusiy = omay - 1
    if suunta == "a":
        uusiy = omay + 1
    if suunta == "v":
        uusix = omax - 1
    if suunta == "o":
        uusix = omax + 1
    if kartta[uusiy][uusix] == 0:
        kartta[omay][omax] = 0
        kartta[uusiy][uusix] = 2
        omay = uusiy
        omax = uusix

Ohjelman tulostus voi olla seuraava:

######
#@##
#    #
# ## #
#    #
######
Suunta (y/a/v/o): a
######
# ##
#@   #
# ## #
#    #
######
Suunta (y/a/v/o): o
######
# ##
# @  #
# ## #
#    #
######
Suunta (y/a/v/o): o
######
# ##
#  @ #
# ## #
#    #
######
Suunta (y/a/v/o): o
######
# ##
#   @#
# ## #
#    #
######
Suunta (y/a/v/o): y
######
# ##@
#    #
# ## #
#    #
######
Suunta (y/a/v/o): o
######
# ## @
#    #
# ## #
#    #
######
Pääsit maaliin!

Muuttujissa omay ja omax on pelaajan sijainti labyrintissa. Kun pelaaja ilmoittaa liikesuunnan, muuttujiin uusiy ja uusix tulee pelaajan uusi sijainti. Jos sijainti kelpaa (pelaaja ei mene seinän päälle), muuttujat kartta, omay ja omax päivittyvät.

Sanakirja

Sanakirja on Python-kielen tietorakenne, josta voi hakea kätevästi tietoa hakuavaimen avulla. Sanakirja muistuttaa listaa, mutta siinä alkioiden tunnukset saa valita itse järjestyksessä olevien kokonaislukujen sijaan.

Seuraava ohjelma kääntää sanan suomesta hollanniksi:

sanat = {
    "talo": "huis",
    "metsä": "bos",
    "katu": "straat",
    "auto": "auto",
    "puu": "boom"
}
sana = input("Anna sana: ")
if sana in sanat:
    print("Hollanniksi:", sanat[sana])
else:
    print("Tuntematon sana!")

Ohjelman tulostus voi olla seuraava:

Anna sana: katu
Hollanniksi: straat

Sanakirja merkitään aaltosulkujen sisään, ja hakuavaimia ja arvoja erottavat kaksoispisteet. Tässä sanakirjan hakuavaimet ovat suomen kielen sanoja, ja niitä vastaavat hollannin kielen sanat. Esimerkiksi sanat["katu"] on "straat" ja sanat["puu"] on "boom".

Esimerkki: Sanalaskuri

Seuraava ohjelma laskee, kuinka monta kertaa käyttäjä kirjoittaa eri sanoja:

sanat = {}

while True:
    sana = input("Anna sana: ")
    if sana == "":
        break
    if sana in sanat:
        sanat[sana] += 1
    else:
        sanat[sana] = 1

for sana in sanat:
    print("Kirjoitit", sanat[sana], "kertaa sanan", sana)

Ohjelman tulostus voi olla seuraava:

Anna sana: banaani
Anna sana: apina
Anna sana: banaani
Anna sana: cembalo
Anna sana: apina
Anna sana: apina
Anna sana:
Kirjoitit 2 kertaa sanan banaani
Kirjoitit 1 kertaa sanan cembalo
Kirjoitit 3 kertaa sanan apina

Tässä sanakirjan hakuavaimet ovat käyttäjän kirjoittamat sanat. Jos käyttäjä kirjoittaa uuden sanan, ohjelma lisää sanakirjaan sen arvoksi 1. Jos käyttäjä kirjoittaa saman sanan uudestaan, ohjelma kasvattaa sen arvoa sanakirjassa.

Esimerkki: Anagrammit

Seuraava ohjelma etsii suomen kielen sanalistasta anagrammeja eli sanoja, jotka sisältävät yhtä monta jokaista kirjainta. Ohjelma tulostaa kaikki sanaryhmät, joissa sanat ovat toistensa anagrammeja ja sanoja on ainakin viisi.

Suomen kielen sanalista esiintyi aiemmin oppaassa 8.

tiedosto = open("kotus_sanat.txt", "r", encoding = "latin-1")
sanat = tiedosto.readlines()
tiedosto.close()

anagrammit = {}
avaimet = []

def jarjesta(sana):
    merkit = list(sana)
    merkit.sort()
    return "".join(merkit)

for sana in sanat:
    sana = sana.strip()
    avain = jarjesta(sana)
    if avain not in anagrammit:
        anagrammit[avain] = [sana]
        avaimet.append(avain)
    else:
        anagrammit[avain].append(sana)

for avain in avaimet:
    if len(anagrammit[avain]) >= 5:
        for sana in anagrammit[avain]:
            print(sana, end = ", ")
        print()

Ohjelman tulostus on seuraava:

alistuva, luistava, ulvaista, valistua, vilustaa,
altis, lasti, lista, litsa, silat, silta, tilsa,
altistaa, laastita, lasittaa, latistaa, salaatti,
altistua, istualta, lasittua, latistua, sulittaa, tulistaa,
aluksi, kilaus, liukas, liuska, luiska, saluki, sulkia,
anturi, nutria, rutina, tunari, turina,
aristus, irstaus, rasitus, surista, tussari,
karsia, kasari, raikas, raiska, raksia, raskia,
keriä, kierä, kireä, reikä, räike,
kiulu, kuilu, liuku, luiku, ukuli,
otsa, sato, sota, taos, taso,
paristo, pastori, pirstoa, porista, ropista,
ravet, tarve, terva, varte, verta,

Ohjelma tallentaa sanat sanakirjaan listoihin, joissa kaikki sanat ovat toistensa anagrammeja. Sanasta muodostettava hakuavain sisältää sanan kirjaimet aakkosjärjestyksessä, jolloin kahdella sanalla on sama avain, jos ne ovat anagrammeja, ja kahdella sanalla on eri avain, jos ne eivät ole anagrammeja.

Esimerkiksi sanan "anturi" hakuavain on "ainrtu" ja sanakirjan kohdassa anagrammit["ainrtu"] on lopuksi lista ["anturi", "nutria", "rutina", "tunari", "turina"].

Funktiossa jarjesta funktio list muuttaa ensin merkkijonon listaksi, jonka alkiot ovat merkkijonon kirjaimet. Listan järjestämisen jälkeen metodi join muuttaa listan takaisin merkkijonoksi lisäämällä listan jokaisen alkion väliin tyhjän merkkijonon.

Avaimet tallennetaan erilliseen listaan, jotta ne pysyvät aakkosjärjestyksessä.


Kirjoita kommentti

Huomio! Kommentoi tässä ainoastaan tämän oppaan hyviä ja huonoja puolia. Älä kirjoita muita kysymyksiä tähän. Jos koodisi ei toimi tai tarvitset muuten vain apua ohjelmoinnissa, lähetä viesti keskusteluun.

Muista lukea kirjoitusohjeet.
Tietoa sivustosta