Skip to content

Løkker, lister og ordbøker

OBS! Dette notatet er gammelt. Les heller kapitlene om løkker, lister og ordbøker i Smidig IT2.

Løkker, lister og ordbøker er veldig viktig i databehandling, derfor tar vi en liten repetisjon fra IT1.

While-løkker kjører “så lenge” en betingelse er sann.

while betingelse:
# kode som gjennomføres så lenge betingelsen er sann

For eksempel bruker programmet under en while-løkke for å telle ned fra 5, og deretter si “lift off!”:

While-løkker brukes som oftest når vi ikke vet hvor lenge vi skal holde på. For eksempel helt til en spiller dør i et spill, eller så lenge spilleren ikke har gjettet riktig, som i eksemplet under.

import random
hemmelig = random.randint(1,100) # trekker et tilfeldig tall fra 1 til 100
gjett = int(input("Hvilket tall tenker jeg på? 1-100: ")) # henter input fra bruker og lagre den i variabelen gjett
while hemmelig != gjett: # så lenge hemmelig ikke er lik gjett
gjett = int(input("Feil, prøv igjen! 1-100: ")) # hent ny input fra bruker og oppdater variabelen gjett
print("Riktig!") # while-løkken er ferdig, som betyr at brukeren har gjettet riktig

While-løkkene kjører så lenge betingelsen er sann (True). Hvis betingelsen aldri blir usann (False), vil en løkke kjøre for alltid. Hvis vi ender opp i en uendelig løkke vil PCen fryse, og vi får ikke kjørt resten av programmet.

Tips: ctrl + c stopper programmet i terminalen.

Eksempel 1:

while True:
print("Inn i evigheten!")

Eksempel 2:

n = 20
while n > 0:
print(n)

En for-løkke er en løkke som kan brukes for å gå gjennom ting, for eksempel kan vi bruke en for-løkke for å gå gjennom hver bokstav i en tekst, hver ting i en liste eller hvert opplslagsord i en ordbok.

Koden under bruker en for-løkke og går gjennom hver bokstav i teksten Ja, vi elsker og teller antall mellomrom.

Inne i en for-løkke lages en variabel, for eksempel bokstav. For hver runde i løkken oppdateres variabelsen verdi, i eksempelene over har variabelen bokstav først verdien "J", så "a", så ",", så " " og så videre. Følg med på hva som skjer i minnet (global frame) i eksempelet over.

Vi kan også bruke for-løkker for å gå gjennom lister. Da vil variabelen vi oppretter i løkken få verdiene til hvert element i listen, en verdi om gangen. Legg merke til hvilke verdier variabelen elev har i eksempelet under.

En liste i python skrives mellom firkantparenteser ["dette", "er", "en", "liste"].
Firkantparenteser skrives med option/alt + shift + 8 på mac.
Firkantparenteser skrives med Alt gr + 8 på windows.

Det er også mulig å bruke for-løkker på lister med tall. Eksempelet under skriver ut syv-gangen.

print("7-gangen")
for tall in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
gange = 7 * tall
print(f"7 * {tall} = {gange}")
Klikk for Pythontutor

I lengden blir det litt slitsomt å skrive alle tallene i listen. Vi kan heller bruke den innebygde funksjonen range(start, slutt_før), som gir oss et intervall fra og med start opp til slutt_før.

range() er en innebygd funksjon som lager en rekke med tall. Rekken starter på det første tallet og slutter ett tall før det andre tallet. Eks: range(1,3) gir rekken 1 2. range(5,7) gir rekken 5 6. Det er også mulig å droppe første tallet i range, slik range(3), da lager range en rekke som starter på 0 og slutter før tallet mellom parantesene. Eks: range(3) gir rekken 0 1 2

print("7-gangen")
for tall in range(1,11):
gange = 7 * tall
print(f"7 * {tall} = {gange}")
Klikk for Pythontutor

Legg merke til at range slutter én før den siste verdien som sendes inn. Løkken under vil altså telle fra 1 til 10 – ikke fra 1 til 11!

for tall in range(1,11):
print(tall)
Klikk for Pythontutor

I mange tilfeller kan vi velge om vi skal bruke for eller while. I eksemplet under brukes både en while-løkke og en for-løkke for å telle til 10.

# ---- While ----
i = 1
while i < 11:
print(i)
i += 1
# ---- For -----
for i in range(11):
print(i)
Klikk for Pythontutor

Selv om det er mulig å bruke begge typene løkker for å løse samme problem, er det noen tilfeller hvor vi oftere bruker for, og andre tilfeller hvor vi oftere bruker while. For-løkker brukes som oftest når vi vet hvor mange ganger vi skal gjenta en kode, mens While-løkker brukes oftest når vi ikke vet hvor mange ganger vi skal gjenta en kode.

Hvis man kjører en for-løkke på en ordbok, vil variabelen inne i løkken gå gjennom alle nøklene i ordboken. I eksempelet under vil variabelen nøkkel har verdiene fornavn, etternavn, alder og klubb. Videre brukes variebelen nøkkel for å hente ut verdiene fra ordboken i print-en.

fotballspiller = {
"fornavn": "Ada",
"etternavn": "Hegerberg",
"alder": 26,
"klubb": "Lyon"
}
for nøkkel in fotballspiller:
print(f"{nøkkel}: {fotballspiller[nøkkel]}")
Klikk for Pythontutor

Lister med ordbøker er en veldig vanlig datastruktur, som vi kommer til å bruke mye i IT2. Under er et eksempel på en liste med ordbøker, der hver ordbok inneholder informasjon om en skuespiller.

skuespillere = [
{"navn": "Tom Hanks", "alder": 66},
{"navn": "Meryl Streep", "alder": 73},
{"navn": "Leonardo DiCaprio", "alder": 48},
{"navn": "Julia Roberts", "alder": 55},
{"navn": "Denzel Washington", "alder": 67},
{"navn": "Nicole Kidman", "alder": 55},
{"navn": "Brad Pitt", "alder": 59},
{"navn": "Charlize Theron", "alder": 47},
{"navn": "Johnny Depp", "alder": 59},
{"navn": "Emma Stone", "alder": 34},
]

Vi kan hente ut en skuepspiller fra listen med firkantparenteser og printe informasjon om skuespilleren.

print(skuespillere[1]) # -> {"navn": "Meryl Streep", "alder": 73}
skuespiller = skuespillere[2] # lager en variabel som peker på ordboken til Leonardi DiCaprio
print(f"{skuespiller['navn']} er {skuespiller['alder']} år gammel") # -> Leonardi DiCaprio er 48 år gammel

Vi kan bruke en for løkke for å gå gjennom alle skuespillerne, da vil variabelen inne i for-løkken etter tur peke på hver enkelt ordbok.

for skuespiller in skuespillere:
print(f"{skuespiller['navn']} er {skuespiller['alder']} år gammel")
Klikk for Pythontutor

Det finnes mange bruksområder for lister og ordbøker, og er man litt kreativ kan man bruke de for å løse en del problemer. I eksempelet under brukes en ordbok for å telle antall sjåfører av forskjellige nasjonaliteter i Formel 1-sirkuset.

f1_sjåfører = [
{"navn": "Lewis Hamilton", "nasjonalitet": "britisk", "team": "Mercedes", "bilnummer": 44},
{"navn": "Daniel Ricciardo", "nasjonalitet": "australsk", "team": "McLaren", "bilnummer": 3},
{"navn": "Lando Norris", "nasjonalitet": "britisk", "team": "McLaren", "bilnummer": 4},
{"navn": "Esteban Ocon", "nasjonalitet": "fransk", "team": "Alpine", "bilnummer": 31},
{"navn": "George Russell", "nasjonalitet": "britisk", "team": "Williams", "bilnummer": 63},
{"navn": "Pierre Gasly", "nasjonalitet": "fransk", "team": "AlphaTauri", "bilnummer": 10},
]
antall_nasjonaliteter = {} # en tom ordbok som skal fylles med nasjonaliteter
for sjåfør in f1_sjåfører: # for hver sjåfør i lista:
nasjonalitet = sjåfør['nasjonalitet'] # hent ut nasjonaliteten til sjårføren
if nasjonalitet not in antall_nasjonaliteter: # hvis nasjonaliteten ikke er en nøkkel i ordboken:
antall_nasjonaliteter[nasjonalitet] = 1 # legg til nasjonaliteten i ordboken med verdien 1
else: # nasjonaliteten finnes allerede i ordboken:
antall_nasjonaliteter[nasjonalitet] += 1 # øk verdien til nasjonaliteten med 1
print(antall_nasjonaliteter) # print ordboken
# {
# 'britisk': 3,
# 'finsk': 2,
# 'nederlandsk': 1,
# 'meksikansk': 1,
# 'monegaskisk': 1,
# 'spansk': 2,
# 'australsk': 1,
# 'fransk': 2,
# 'tysk': 2,
# 'canadisk': 1,
# 'italiensk': 1,
# 'russisk': 1,
# 'kanadisk': 1,
# 'japansk': 1
# }
Klikk for Pythontutor

I utgangspunktetet kan ikke ordbøker sorteres, så hvis vi for eksempel ønsker å sortere nøklene i en ordbok etter verdier, må vi konvertere ordboken til en liste.

personer = {
"Ravi": 39,
"Thor": 33,
"Martin": 34
}
# lager en liste av tupler som kan sorteres (tupler er nesten som lister, så du kan tenke at vi lager en liste av lister)
personer_liste = personer.items() # -> [('Ravi', 39), ('Thor', 33), ('Martin', 34)]
personer_sortert = sorted(personer_liste, key=lambda person: person[1]) # sorterer listen på det som ligger på plassering [1], altså verdien
print(personer_sortert) # -> [('Thor', 33), ('Martin', 34) ('Ravi', 39)]
print(personer_sortert[0][0]) # -> 'Thor'