Kirjoittaja: Antti Laaksonen (2009).
⚠ Huomio! Tämä opas on vanhentunut. Oppaan sisältöön ei voi enää luottaa. Opas on säilytetty vain sen historiallisen arvon vuoksi. ⚠
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.
Seuraavassa ohjelmassa listan sisällä on kolme alilistaa:
# -*- coding: latin-1 -*- 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, 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ää.
Seuraava ohjelma tulostaa pelin tuloslistan:
# -*- coding: latin-1 -*- 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ä.
Seuraava ohjelma piirtää labyrintin listan perusteella:
# -*- coding: latin-1 -*- 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], 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:
# -*- coding: latin-1 -*- 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], print if omay == 1 and omax == 5: print "Pääsit maaliin!" break suunta = raw_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 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:
# -*- coding: latin-1 -*- sanat = {"talo":"huis", "metsä":"bos", "katu":"straat", "auto":"auto", "puu":"boom"} sana = raw_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"
.
Seuraava ohjelma laskee, kuinka monta kertaa käyttäjä kirjoittaa eri sanoja:
# -*- coding: latin-1 -*- sanat = {} while True: sana = raw_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.
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.
# -*- coding: latin-1 -*- tiedosto = open("kotus_sanat.txt", "r") sanat = tiedosto.readlines() tiedosto.close() anagrammit = {} 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] else: anagrammit[avain].append(sana) for avain in anagrammit: if len(anagrammit[avain]) >= 5: for sana in anagrammit[avain]: print sana, print
Ohjelman tulostus on seuraava:
anturi nutria rutina tunari turina alistuva luistava ulvaista valistua vilustaa altis lasti lista litsa silat silta tilsa altistaa laastita lasittaa latistaa salaatti keriä kierä kireä reikä räike aristus irstaus rasitus surista tussari altistua istualta lasittua latistua sulittaa tulistaa ravet tarve terva varte verta paristo pastori pirstoa porista ropista aluksi kilaus liukas liuska luiska saluki sulkia karsia kasari raikas raiska raksia raskia kiulu kuilu liuku luiku ukuli otsa sato sota taos taso
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.
Huippu ohjelma, nopeasti tajuaa ohjelmoinnin juonen..
Tein tuommosen muunnelman labyrintistä mutta en saanut tuota breik:kiä jostain syystä toimimaan (while True ei `katkea`)
# -*- coding: latin-1 -*- kartta = [[1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 2, 1, 0, 0, 0, 0, 1, 1], [1, 0, 0, 0, 1, 1, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 1, 1, 1, 1, 0, 1, 1], [1, 1, 1, 0, 0, 1, 0, 0, 1], [0, 0, 1, 1, 0, 0, 1, 0, 1], [1, 0, 1, 1, 1, 0, 1, 0, 1], [1, 0, 0, 0, 1, 0, 0, 0, 1], [1, 1, 1, 0, 0, 0, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1]] pisteet = 0 omay = 1 omax = 1 merkit = " XO" while True: for rivi in kartta: for ruutu in rivi: print merkit[ruutu], print if omay == 7 and omax == 0: pisteet +=10 print "Pääsit maaliin, Saat 10 lisäpistettä!" if pisteet == 12: print "Löysit myös kummankin kaverisi! Pisteet: ", pisteet if pisteet == 11: print "Löysit yhden kaverinkin matkanvarrelta! Pisteet: ", pisteet if pisteet == 10: print "Et löytänyt yhtään kaveria.. Pisteet: ", pisteet break if omay == 5 and omax == 1: print "Löysit kaverin! +1 piste" pisteet +=1 if omay == 6 and omax == 3: print "Löysit kaverin! +1 piste" pisteet +=1 suunta = raw_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
Jormapythoni kirjoitti:
Huippu ohjelma, nopeasti tajuaa ohjelmoinnin juonen..
Tein tuommosen muunnelman labyrintistä mutta en saanut tuota breik:kiä jostain syystä toimimaan (while True ei `katkea`)
Itse sain ton sun labyrintin toimimaan lisäämällä
if pisteet > 2: break
Toivottavasti auttoi!
Jormapythoni kirjoitti:
Huippu ohjelma, nopeasti tajuaa ohjelmoinnin juonen..
Tein tuommosen muunnelman labyrintistä mutta en saanut tuota breik:kiä jostain syystä toimimaan (while True ei `katkea`)
Hienon labyrintin väsäsit! Sain ainakin noin toimimaan, mutta huomasin samalla että saman henkilön voi poimia useamman kerran. En itse keksinyt miten sen saisi vielä korjattua.
# -*- coding: latin-1 -*- kartta = [[1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 2, 1, 0, 0, 0, 0, 1, 1], [1, 0, 0, 0, 1, 1, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 1, 1, 1, 1, 0, 1, 1], [1, 1, 1, 0, 0, 1, 0, 0, 1], [0, 0, 1, 1, 0, 0, 1, 0, 1], [1, 0, 1, 1, 1, 0, 1, 0, 1], [1, 0, 0, 0, 1, 0, 0, 0, 1], [1, 1, 1, 0, 0, 0, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1]] pisteet = 0 omay = 1 omax = 1 merkit = " XO" while True: for rivi in kartta: for ruutu in rivi: print merkit[ruutu], print if omay == 7 and omax == 0: pisteet +=10 print "Pääsit maaliin, Saat 10 lisäpistettä!" break if omay == 5 and omax == 1: print "Löysit kaverin! +1 piste" pisteet +=1 if omay == 6 and omax == 3: print "Löysit kaverin! +1 piste" pisteet +=1 suunta = raw_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 if pisteet > 12: print "Nyt taisit huijata :)" if pisteet == 12: print "Löysit myös kummankin kaverisi! Pisteet: ", pisteet if pisteet == 11: print "Löysit yhden kaverinkin matkanvarrelta! Pisteet: ", pisteet if pisteet == 10: print "Et löytänyt yhtään kaveria.. Pisteet: ", pisteet
Tahdoin vain laittaa tähän tekemäni muunnelman labyrintistä, siellä on nyt myös ansa ja mörkö.
# -*- coding: latin-1 -*- 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, 3, 0, 1], [1, 1, 1, 1, 1, 1]] omay = 1 omax = 1 morkoy = 4 morkox = 3 ansay = 3 ansax = 4 merkit = " #@ö" while True: for rivi in kartta: for ruutu in rivi: print merkit[ruutu], print if omay == 1 and omax == 5: print "Pääsit maaliin!" break suunta = raw_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 if omay == ansay and omax == ansax: print "Astuit ansaan ja kuolit lol." break if omay == morkoy - 1 or omay == morkoy + 1 or omay == morkoy: if omax == morkox -1 or omax == morkox +1 or omax == morkox: print "Mörkö söi sut ja kuolit." break
Huomasin että sanakirjan hyödyllinen items-metodi on jätetty esittelemättä tässä oppaassa. Sen avulla on helppo iteroida sanakirjan avain-arvo-pareja. Esim. Sanalaskuri-esimerkin kohta
for sana in sanat: print "Kirjoitit", sanat[sana], "kertaa sanan", sana
on items-metodin kanssa tällainen:
for sana, n in sanat.items(): print "Kirjoitit", n, "kertaa sanan", sana
Vaihtoehtoisesti merkkijonoja voi koostaa %-operaattorilla näin:
for sana, n in sanat.items(): print "Kirjoitit %d kertaa sanan %s" % (n, sana)
Uusin (Python 2.6 ja myöhemmät), selkein ja joustavin tapa on käyttää nimettyjä paikanosoittimia merkkijonon format-metodin kanssa:
for sana, n in sanat.items(): print "Kirjoitit {n} kertaa sanan {s}".format(n=n, s=sana)
Lisätietoa format-metodin tarjoamista monipuolisista ominaisuuksista:
https://docs.python.org/2/library/string.html#format-specification-mini-language
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.