Bruke dictionaries

I denne artikkelen skal vi utforske dictionaries gjennom et eksempel der vi teller forekomster av tegn i en streng. Vi skal skrive kode som går gjennom en streng og skriver ut antall forekomster av tegn i strengen, sortert alfabetisk. Med strengen "bare barn er barn, men alle er vi barnebarn", skal vi få skrevet ut en slik oversikt:
[(' ', 8), (',', 1), ('a', 6), ('b', 5), ('e', 6), ('i', 1), ('l', 2), ('m', 1), ('n', 5), ('r', 7), ('v', 1)]
 Altså informasjon om at strengen inneholder åtte blanke, ett komma, seks a-er, og så videre.

Vi utvikler koden skrittvis, og starter med kode som ikke gjør annet enn å skrive ut tegnene i strengen den får inn.

Skritt 1

Vi benytter oss av at vi kan bruke ei for-løkke til å hente ut ett og ett tegn fra en streng.

streng = "bare barn er barn, men alle er vi barnebarn"
for tegn in streng:
    print(f"'{tegn}'", end = " ")

Når vi gir inn end = " " til print(), betyr det at vi skal ha et blankt tegn etter hver utskrift, ikke linjeskift, slik det beskrives i artikkelen om å formatere utskrifter.

Når vi kjører koden, får vi skrevet ut

'b' 'a' 'r' 'e' ' ' 'b' 'a' 'r' 'n' ' ' 'e' 'r' ' ' 'b' 'a' 'r' 'n' ',' ' ' 'm' 'e' 'n' ' ' 'a' 'l' 'l' 'e' ' ' 'e' 'r' ' ' 'v' 'i' ' ' 'b' 'a' 'r' 'n' 'e' 'b' 'a' 'r' 'n' 

Skritt 2

Nå endrer vi koden slik at den legger tegnene inn i en dictionary i stedet for å skrive dem ut. Til dette bruker vi dictionary-metoden update(). Som det står i artikkelen om dictionaries, vil update() oppdatere hvis en nøkkel finnes fra før, legge til hvis ikke. I denne første versjonen teller vi ikke forekomster, vi registrerer bare et spørsmålstegn sammen med hver nøkkel. Til slutt skriver vi dictionary ut.

streng = "bare barn er barn, men alle er vi barnebarn"
antall = {}  # Tom dictionary
for tegn in streng:
    antall.update({tegn: "?"})
print(antall)

Når vi kjører koden, får vi skrevet ut

{'b': '?', 'a': '?', 'r': '?', 'e': '?', ' ': '?', 'n': '?', ',': '?', 'm': '?', 'l': '?', 'v': '?', 'i': '?'} 

Skritt 3

Nå begynner vi å bruke dictionary til å telle forekomster av tegn, i stedet for å bare legge inn spørsmålstegn. Vi sjekker om et tegn ligger i dictionary fra før. Hvis det gjør, leser vi hvor mange ganger forekomster det har så langt, og øker denne med 1. Hvis et tegn ikke ligger i dictionary fra før, registrerer vi det med 1 forekomst.

streng = "bare barn er barn, men alle er vi barnebarn"
antall = {}  # Tom dictionary
for tegn in streng:
    if tegn in antall:
        tidl = antall.get(tegn)  # Antall tidligere forekomster
        antall.update({tegn: tidl + 1})  # Øk antall forekomster med 1
    else:
        antall.update({tegn: 1})  # Registrer 1 forekomst
print(antall)

Når vi kjører koden, får vi skrevet ut

{'b': 5, 'a': 6, 'r': 7, 'e': 6, ' ': 8, 'n': 5, ',': 1, 'm': 1, 'l': 2, 'v': 1, 'i': 1}

Skritt 4

Nå fungerer koden. Vi kan imidlertid forenkle den mye ved å benytte oss av at vi i dictionary-metoden get() kan angi hva vi vil ha returnert hvis en nøkkel ikke finnes i dictionary. Dette lar vi så være 0.

streng = "bare barn er barn, men alle er vi barnebarn"
antall = {} # Tom dictionary
for tegn in streng:
    # Øk antall forekomster med 1
    tidl = antall.get(tegn, 0)  
    antall.update({tegn: tidl + 1})
print(antall)

Vi kan også droppe mellomvariabelen tidl, og bare skrive

streng = "bare barn er barn, men alle er vi barnebarn"
antall = {} # Tom dictionary
for tegn in streng:
    # Øk antall forekomster med 1
    antall.update({tegn: antall.get(tegn, 0) + 1})
print(antall)

Skritt 5

Nå gjenstår det bare å sortere forekomstene alfabetisk. Det gjør vi med Python-funksjonen sorted(). For å få med verdiene og ikke bare nøklene, må vi imidlertid også bruke dictionary-metoden items(), slik det beskrives i artikkelen om å gjennomløpe dictionaries.

streng = "bare barn er barn, men alle er vi barnebarn"
antall = {} # Tom dictionary
for tegn in streng:
    # Øk antall forekomster med 1
    antall.update({tegn: antall.get(tegn, 0) + 1})
antall = sorted(antall.items())
print(antall)

Når vi kjører koden, får vi skrevet ut

[(' ', 8), (',', 1), ('a', 6), ('b', 5), ('e', 6), ('i', 1), ('l', 2), ('m', 1), ('n', 5), ('r', 7), ('v', 1)]

Bruken av items() gjør at dette ikke lenger er en dictionary.

Oppgave 1:

Koden under bruker funksjonen randint() fra modulen random til å simulere kast med to terninger og registrere summen av antall øyne på de to terningene.

from random import randint
 
oyne = randint(1, 6) + randint(1, 6)

Skriv Python-kode som gjør en million slike simuleringer og teller opp og skriver ut hvor ofte de forskjellige summene av øyne forekommer. Utskriften skal være sortert på sum øyne. Antallet forekomster vil variere fra kjøring til kjøring, men skal ha format som dette:

[(2, 27660), (3, 56008), (4, 83074), (5, 111486), (6, 139296), (7, 166093), (8, 138523), (9, 111072), (10, 83480), (11, 55679), (12, 27629)]

Se løsningsforslag

Kilder

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