Dictionaries

Dataypen dictionary

I artikkelen om lister presenterer vi datatypen lister som variabler som kan inneholde flere verdier. I ei liste er elementene nummerert fra 0 og oppover, og vi identifiserer et element ved hjelp av navnet på lista og en indeks, som er et løpenummer som starter på 0. Hvis for eksempel partall er ei liste, er partall[0] det første elementet i lista, med indeks 0.

Nå skal vi se på en annen datatype som kan inneholde flere verdier, dictionaries. Vi velger å bruke det engelske navnet fordi den norske oversettelsen, ordbøker, er misvisende.

Til forskjell fra i lister bruker vi en nøkkel, ikke en indeks, til å navigere i en dictionary. Når vi slår opp med nøkkelen, får vi ut den tilhørende verdien.

En dictionary inneholder et vilkårlig antall par av nøkler og verdier. Vi kan opprette en dictionary ved å ramse opp innholdet på samme måte som i ei liste, men vi bruker krøllparenteser, ikke klammeparenteser, og innholdet oppgis som par av nøkler og verdier med kolon mellom.

Eksempel 1:

Vi oppretter dictionary antall_hjul:

antall_hjul = {"sykkel": 2, "moped": 2, "bil": 4, "ATV": 4}

Her er nøklene navnene på forskjellige typer kjøretøy, og verdiene er antall hjul kjøretøyene har.

Stilguiden PEP 8 anbefaler mellomrom etter, men ikke foran, kolon i dictionaries.

Har vi mer enn noen få nøkkel-verdi-par, blir gjerne en dictionary for lang til få plass på ei linje, da plasserer vi parene under hverandre:

antall_hjul = {
    "sykkel": 2,
    "moped": 2,
    "bil": 4,
    "ATV": 4
    }

Innrykkene er ikke noe krav i Python, men anbefales i PEP 8.

Vi kan skrive ut alle parene i en dictionary med print() på samme måte som i ei liste. For å se hvordan antall_hjul fra eksempel 1 ser ut, skriver vi

print(antall_hjul)

For å slå opp i en dictionary kan vi bruke dictionary-navnet etterfulgt av nøkkelen i klammeparentes. Her bruker vi altså samme type parentes som i lister, ikke krøllparentes.

Basert på antall_hjul i eksempel 1 vil

print(antall_hjul["sykkel"])

skrive ut 2.

I eksempel 1 var nøklene strenger og verdiene tall. Men nøklene kan også godt være tall.

Eksempel 2:

Vi oppretter dictionary siffer_norsk:

siffer_norsk = {
    1: "en",
    2: "to",
    3: "tre",
    4: "fire",
    5: "fem",
    6: "seks",
    7: "syv",
    8: "åtte",
    }

Her er nøklene sifrene fra 1 til 8, og verdiene er sifrenes navn på norsk.

Skriver vi for eksempel

print(siffer_norsk[3])

får vi skrevet ut tre.

På samme måte som ved lister kan vi bruke kodeordet in til å avgjøre om en nøkkel finnes i en dictionary. Hvis dict er en dictionary og k en nøkkel, vil uttrykket k in dict være True hvis k finnes i dictFalse hvis ikke. 

Basert på siffer_norsk i eksempel 2, vil for eksempel 

print(5 in siffer_norsk)
print(9 in siffer_norsk)

skrive ut henholdsvis True og False, fordi 5 er en nøkkel i siffer_norsk, men ikke 9.

Vil vi sjekke om en verdi ligger i en dictionary, må vi involvere dictionary-metoden values(). Hvis dict er en dictionary og v en verdi, vil uttrykket v in dict.values() være True hvis v finnes i dictFalse hvis ikke.

Basert på siffer_norsk i eksempel 2, vil for eksempel 

print("fem" in siffer_norsk.values())
print("ni" in siffer_norsk.values())

skrive ut henholdsvis True og False, fordi "fem" er en verdi i siffer_norsk, men ikke "ni".

Dictionary-metoder

På samme måte som lister, har også dictionaries metoder knyttet til seg. En oversikt finnes her: https://www.w3schools.com/python/python_ref_dictionary.asp

Vi skal presentere noen av dem.

update()

Denne metoden kan brukes til å endre eller legge til innhold i en dictionary. Som argument til update() gir vi ett eller flere par med nøkler og verdier mellom krøllparenteser. Hvis en nøkkel finnes i dictionary fra før, blir den tilhørende verdien oppdatert. Hvis ikke, blir et nytt nøkkel-verdi-par lagt til.

Eksempel 3:

Vi har dictionary siffer_norsk fra eksempel 2, og skriver

siffer_norsk.update({7: "sju"})
siffer_norsk.update({0: "null"})

Nøkkelen 7 finnes fra før, så verdien knyttet til 7 blir endret fra "syv" til "sju".

Nøkkelen 0 finnes ikke, så paret 0: "null" blir lagt til.

Vi kan oppnå det samme uten update() ved å bruke nøklene direkte:

siffer_norsk[7] = "sju"
siffer_norsk[0] = "null"

Det blir smak og behag hva vi velger. Med update() kan vi imidlertid angi flere par samtidig, og utføre det vi gjorde i to operasjoner over i én enkelt operasjon:

siffer_norsk.update({7: "sju", 0: "null"})

Nye par legges fortløpende til på slutten. Så i eksempel 3 vil 0 bli lagt til etter 8.

pop()

Fjerner et par med en nøkkel vi gir inn som argument.

Eksempel 4:

Vi har dictionary siffer_norsk fra eksempel 2 og skriver

siffer_norsk.pop(5)

Da blir paret 5: "fem" fjernet fra siffer_norsk.

Hvis nøkkelen ikke finnes i dictionary, genererer Python feilkoden KeyError.

På samme måte som i lister, returnerer pop() verdien den fjerner, og denne verdien kan vi tilordne til en variabel. Skriver vi for eksempel poppet = siffer_norsk.pop(5), får variabelen poppet verdien «fem».

popitem()

Fjerner siste nøkkel-verdi-par som ble lagt inn i dictionary.

get()

Slår opp med en nøkkel vi gir inn som et argument, og returnerer den tilhørende verdien. I motsetning til pop() og popitem() fjerner imidlertid ikke get() noe fra dictionary.

Eksempel 5:

Vi har dictionary siffer_norsk fra eksempel 2 og skriver

print(siffer_norsk.get(4))

Da får vi skrevet ut fire.

Dette er det samme som å slå opp direkte med 4 som nøkkel:

print(siffer_norsk[4])

I eksempel 5 så vi at vi at vi kan slå opp i en dictionary både ved å bruke metoden get() og ved å skrive navnet på dictionary etterfulgt av nøkkelen i klammeparentes. Den siste metoden vil imidlertid gi feilkoden KeyError hvis nøkkelen ikke finnes i dictionary, mens get() vil returnere None. Det er også mulig å gi inn et argument til get() som skal returneres hvis nøkkelen ikke finnes.

Eksempel 6:

Vi har dictionary siffer_norsk fra eksempel 2 og skriver

print(siffer_norsk[9])

Da får vi en feilmelding, og Python genererer KeyError, fordi 9 ikke er en nøkkel i siffer_norsk.

Skriver vi i stedet

print(siffer_norsk.get(9))

Får vi skrevet ut None.

Skriver vi

print(siffer_norsk.get(9, "Ukjent nøkkel"))

Får vi skrevet ut Ukjent nøkkel.

clear()

Tømmer en dictionary, det vil si at alt innhold fjernes.

Oppgave 1:

Skriv kode som

        • Oppretter en dictionary som heter landsprefiks, og inneholder følgende nøkkel-verdi-par: "Afghanistan": 93, "Albania": 355, "Algerie": 213, "Andorra": 0, "Angola": 244.
        • Endrer verdien tilknyttet nøkkelen "Andorra" til 376 og legger til paret "Anguilla": 1264.
        • Slår opp og skriver ut verdien knyttet til nøkkelen "Angola".
        • Slår opp og skriver ut meldingen "Ukjent land" ved oppslag med nøkkelen "Argentina".

Se løsningsforslag

Dictionaries har ikke orden på samme måte som lister. I motsetning til i lister spiller rekkefølgen på innholdet ingen rolle. Mens for eksempel lista [1, 2] vil være forskjellig fra [2, 1], der innholdet er byttet om, vil dictionary {1: "a", 2: "b"} være lik {2: "b", 1: "a"}, selv om innholdet er byttet om. Det finnes heller ingen metoder knyttet til bestemte posisjoner i dictionaries, slik som insert(), append() og pop() uten argument, slik vi har i lister.

På den annen side har dictionaries orden i den forstand at innholdet blir liggende i den rekkefølgen det blir lagt inn. Så hvis vi gjennomløper en dictionary med ei for-løkke, vil vi alltid få innholdet ut i samme rekkefølge som vi la det inn. Rekkefølgen forandres heller ikke hvis vi endrer en verdi med update().

Vi velger derfor å si at dictionaries har delvis orden.

Kilder

    • Matthes A. (2019). Python Crash Course. no starch press

I språk som JavaScript og C++ kalles dictionaries associative arrays, eller assosiative tabeller på norsk.