Tilbake
1.3

1.3 Løkker — for, while og range

For- og while-løkker, range med tre argumenter, nøstede løkker og løkketerminering — ryggraden i all koding og i kodesporing.

50 min
10 oppgaver
Løkkerforwhilerange
Din fremgang i kapitlet
0 / 10 oppgaver
Forkunnskaper:

- kap. 1.1 — Variabler, datatyper og konvertering: tilordning, +=, og operatorene // og %.
- kap. 1.2 — Boolsk logikk og betingelser: sammenligninger, and/or, og at en betingelse er et uttrykk med verdien True eller False.

Tar du bare med deg én ting fra dem, la det være denne: en betingelse er noe som er sant eller usant akkurat nå, og verdien kan endre seg mens programmet kjører.

Vil du ha en parallell gjennomgang av løkkene med andre ord, finnes Løkker: for, while og range i et beslektet emne.

Løkke 1 — Å gjenta noe én gang per verdi (~10 min)

En værstasjon har målt temperaturen fire ganger i døgnet. Skal du skrive ut alle fire, kunne du skrevet fire print-linjer. Men stasjonen måler 8 760 ganger i året, og da holder ikke den framgangsmåten.

En løkke er en kodeblokk som gjentas. Den vanligste formen gjentar blokken én gang for hver verdi i en samling.

Løkke

En kodeblokk som kjøres flere ganger. Python har to typer:

- for — når du på forhånd vet hva du skal gå gjennom: hver verdi i en samling, eller hvert tall i et intervall.
- while — når du ikke vet hvor mange runder det blir, bare når du skal stoppe.

Hver gjennomkjøring kalles en runde eller en iterasjon. Å iterere betyr rett og slett å gå gjennom noe, ett element av gangen.

Liste — så mye du trenger her

En liste er flere verdier samlet i én, skrevet mellom hakeparenteser og skilt med komma: [12, 15, 9, 11].

Tre ting trenger du i dette kapitlet: len(liste) gir antall elementer; liste[0] gir det første elementet (plassnummereringen starter på null); og du kan gå gjennom lista med en for-løkke.

Lister har mye mer i seg — indeksering bakfra, utsnitt, metoder for å legge til og fjerne. Alt det kommer i Del 3. Her brukes lista bare som noe å gå gjennom.

`for e in sekvens:`

Kjører den innrykkede blokken én gang for hvert element i sekvensen. Variabelen e peker på elementet i hver runde — ikke på plassnummeret.

En «sekvens» er noe det går an å gå gjennom: en liste, en tekst (da er elementene tegnene), eller et tallintervall laget med range.

Navnet på løkkevariabelen velger du selv. Velg et som sier hva elementet er: for temp in malinger: leser bedre enn for x in y:.

Løkkekropp og innrykk

Alt som skal gjentas, står rykket inn under for-linja. Innrykket er ikke pynt — det er Pythons måte å avgjøre hva som hører til løkka.

Bokas standard er fire mellomrom per nivå, og du skal aldri blande mellomrom og tabulator i samme fil. Gjør du det, stopper Python med IndentationError eller TabError. Dette er felle #16 i bokas feilregister.

Den første linja uten innrykk etter løkka, står utenfor den og kjøres én gang — etter at alle rundene er ferdige.

✏️Eksempel 1: Inne i eller utenfor løkka?

De samme fire linjene, med print plassert to steder. Hva skriver hvert program ut?

Først med print inne i løkka:

malinger = [12, 15, 9, 11]
for temp in malinger:
    print(temp)

Utskrift:

12
15
9
11

Så med print utenfor, altså uten innrykk:

malinger = [12, 15, 9, 11]
for temp in malinger:
    siste = temp
print(siste)

Utskrift:

11

Det andre programmet skriver bare én linje, og den viser den siste verdien løkkevariabelen fikk. Løkka gikk fire runder, men print kjørte én gang.

Legg merke til at både temp og siste fortsatt finnes etter at løkka er ferdig. Variabler som lages inne i en løkke, forsvinner ikke — de beholder sin siste verdi.

📝Oppgave 1

(Innstegsoppgave — minimal sporing. Sjanger B — kodesporing, altså «hva skriver programmet ut?».) Hva skriver programmet ut?

for by in ['Bodø', 'Voss']:
    print(by)
print('ferdig')

Løkke 2 — range, og av-én-fella (~12 min)

Ofte skal du ikke gå gjennom en ferdig samling, men gjennom en tallrekke: de ti første sekundene, hver tredje rad, plassnumrene i en liste. Da bruker du range.

range er den enkeltkonstruksjonen som koster flest poeng på eksamen, og alltid av samme grunn: hvor rekka slutter.

`range(stopp)`

Tallrekka fra og med 0 til, men ikke med, stopp.

range(5) gir 0, 1, 2, 3, 4 — altså fem tall, og det største er 4. Antall runder er stopp, men den siste verdien er stopp - 1.

Det er akkurat denne forskjellen mellom «antall» og «siste verdi» som utløser av-én-feilen.

`range(start, stopp)`

Tallrekka fra og med start til, men ikke med, stopp.

range(1, 5) gir 1, 2, 3, 4 — fire tall. Antall runder er stopp - start.

Skal du telle fra og med 1 til og med 10, skriver du derfor range(1, 11). Den ekstra én-eren i sluttverdien er ikke en feil — den er regelen.

`range(start, stopp, steg)`

Som over, men hopper steg av gangen. stopp er fortsatt eksklusiv.

range(0, 10, 2) gir 0, 2, 4, 6, 8. range(1, 10, 2) gir 1, 3, 5, 7, 9.

De to formene over er det faste paret i eksamensoppgaver: den første gir elementene på plass 0, 2, 4 … («annethvert fra det første»), den andre gir plass 1, 3, 5 … («annethvert fra det andre»). Blander du dem, treffer du helt andre elementer — dette er felle #5 i bokas feilregister.

Negativt steg
range(10, 0, -2) teller nedover: 10, 8, 6, 4, 2. stopp er fortsatt eksklusiv, så nullen er ikke med.

Skal du telle nedover til og med 0, må stoppverdien være -1: range(10, -1, -1) gir 10, 9, 8 … 1, 0.

Med negativt steg må start være større enn stopp. Er den ikke det, blir rekka tom.

Tom `range`
range(0), range(5, 5) og range(0, 5, -1) gir alle ingen tall. Løkka kjører null ganger, helt uten feilmelding.

Det er en vanlig kilde til at «programmet gjør ingenting»: grensene er satt slik at rekka er tom. Når et program mot formodning ikke skriver noe, er en tom range det første du skal mistenke.

På eksamen er dette også et sporingssvar i seg selv: riktig svar kan være at det ikke skrives noe som helst.

`range(len(x))`

Gir plassnumrene 0 til len(x) - 1, altså akkurat de lovlige plassene i sekvensen x. Bruk den når du trenger plassnummeret og ikke bare verdien.

Dette er den eneste formen som lar deg endre elementer: x[i] = ... krever et plassnummer. En vanlig for e in x: gir deg en kopi av verdien, og å tilordne til e endrer ingenting i lista.

Legg merke til at len(x) regnes ut én gang, før løkka starter.

`enumerate(x)`

Gir plassnummer og verdi samtidig, som et par: for i, verdi in enumerate(x): setter i til plassnummeret og verdi til elementet.

Nummereringen starter på 0, akkurat som plassnumrene ellers. Skal du vise et menneskevennlig nummer, legger du til én i utskriften, ikke i løkka.

enumerate er en snarvei, og snarveier er tillatt og brukt i fasit i dette faget. Velg for e in x: når du bare trenger verdien, enumerate når du trenger begge, og range(len(x)) når du skal endre elementer.

Løkkevariabelen etter løkka

Variabelen som løkka brukte, finnes fortsatt når løkka er ferdig, og har sin siste verdi.

Etter for i in range(4): er i lik 3 — ikke 4, og ikke borte. Etter en løkke over en tom range finnes variabelen derimot ikke i det hele tatt, og å bruke den gir NameError.

Det samme gjelder alle variabler som lages inne i kroppen. De overlever løkka, og det er nettopp det som gjør akkumulator- og tellermønsteret mulig.

📜Akkumulatormønsteret

Det kanoniske mønsteret for å bygge opp én verdi av mange. Tre faste deler, i denne rekkefølgen:

s = 0
for i in range(1, 5):
    s += i
print(s)

Utskrift:

10

1. Startverdi før løkka. s = 0 for en sum, p = 1 for et produkt. Står startverdien inne i løkka, nullstilles den hver runde, og resultatet blir bare det siste leddet.
2. Oppdatering inne i løkka, med +=.
3. Bruk av resultatet etter løkka, utenfor innrykket.

Dette mønsteret bærer alle analyseoppgavene senere i boka: summer en kolonne, tell forekomster, finn den beste raden. Lær det her, og du kan det der.

📜Tellermønsteret

Samme skjelett som akkumulatoren, men med en betingelse inni: tell hvor mange elementer som oppfyller et krav.

malinger = [12, 15, 9, 11, 4]
antall = 0
for temp in malinger:
    if temp >= 10:
        antall += 1
print(antall)

Utskrift:

3

1. antall = 0 før løkka.
2. if-testen inne i løkka avgjør om telleren skal økes.
3. antall brukes etter løkka.

Dette er selve grunnformen for «hvor mange …»-deloppgavene i programmeringsdelen. Legg merke til at antall += 1 står ett nivå lenger inn enn if-linja — den hører til betingelsen, ikke til løkka.

✏️Eksempel 2: Fire `range`-varianter

Hva skriver hver av de fire løkkene ut, og hvor mange runder går de?

for i in range(4):
    print(i, end=' ')
print()
for i in range(1, 5):
    print(i, end=' ')
print()
for i in range(1, 10, 2):
    print(i, end=' ')
print()
for i in range(10, 0, -3):
    print(i, end=' ')
print()

Utskrift:

0 1 2 3 
1 2 3 4 
1 3 5 7 9 
10 7 4 1 

print(..., end=' ') bytter ut linjeskiftet med et mellomrom, så tallene havner på samme linje. Den nakne print() etterpå avslutter linja.

LøkkeVerdierAntall runder
range(4)0 1 2 34
range(1, 5)1 2 3 44
range(1, 10, 2)1 3 5 7 95
range(10, 0, -3)10 7 4 14

Legg merke til den siste: neste verdi etter 1 ville vært 2-2, som er forbi stoppverdien, så løkka stopper. Stoppverdien 0 er aldri med.
📝Oppgave 2
Sjanger B

Hvor mange runder går hver løkke, og hva skriver programmet ut?

s = 0
for i in range(3):
    s += i
print(s)
t = 0
for i in range(1, 4):
    t += i
print(t)

📝Oppgave 3
Eksamensnivå, sjanger B

Hva skriver programmet ut?

tall = [4, 7, 2, 9, 5]
for i in range(1, len(tall), 2):
    tall[i] = tall[i] ** 2
print(tall)

📝Oppgave 4
Eksamensnivå,…

En treningslogg er ei liste med antall minutter per økt.

a) Skriv total_tid(okter) som returnerer summen av alle minuttene.
b) Skriv antall_lange(okter) som returnerer hvor mange økter som varte minst 45 minutter.
c) Vis hva de to funksjonene gir for lista [30, 55, 45, 20, 60].

Løkke 3 — Løkke inne i løkke (~10 min)

— naturlig pausepunkt —

En tabell har både rader og kolonner. Skal du gå gjennom alle cellene, trenger du én løkke for radene og én for kolonnene inne i den. Det er dette mønsteret som bærer hele programmeringsdelen senere i boka, så det lønner seg å bruke tid her.

Nøstet løkke

En løkke inne i kroppen til en annen løkke, med ett innrykksnivå til.

Den indre løkka kjøres helt ferdig for hver runde i den ytre. Er grensene uavhengige, blir antall innerste runder produktet: en ytre løkke på 3 og en indre på 4 gir 12 innerste runder.

Rekkefølgen er alltid den samme: ytre runde 1, alle indre runder, ytre runde 2, alle indre runder, og så videre.

Løkkevariabel-avhengige grenser

Den indre grensen kan avhenge av den ytre løkkevariabelen: for j in range(i):.

Da varierer antall indre runder fra ytre runde til ytre runde. Med i lik 0 kjøres den indre løkka null ganger — range(0) er tom, uten feilmelding.

Dette er den vanligste sporingsfella i nøstede løkker, fordi den fristende, men gale antakelsen er at alle ytre runder gir like mange indre.

✏️Eksempel 3: Trekanten som vokser

Hva skriver programmet ut, og hvor mange innerste runder blir det til sammen?

for i in range(1, 4):
    for j in range(i):
        print(i * j, end=' ')
    print()

Utskrift:

0 
0 2 
0 3 6 

Sporing, runde for runde:

Ytre iIndre range(i)j-verdierSkriver
1range(1)00
2range(2)0, 10 2
3range(3)0, 1, 20 3 6

Til sammen 1+2+3=61 + 2 + 3 = 6 innerste runder. Den nakne print() står i den ytre løkka, ikke i den indre — derfor blir det ett linjeskift per rad og ikke ett per tall.
Legg merke til at hver linje slutter med et mellomrom, fordi end=' ' gjelder også det siste tallet på linja. Det synes ikke på skjermen, men det er der.
📝Oppgave 5
Sjanger B

Hva skriver programmet ut?

for i in range(3):
    for j in range(2):
        print(i, j)

📝Oppgave 6
Eksamensnivå, sjanger B

Hva skriver programmet ut? Vær nøye med hvor mange runder den indre løkka går.

s = 0
for i in range(4):
    for j in range(i, 4):
        s += 1
print(s)

Løkke 4 — while: gjenta så lenge noe er sant (~10 min)

— naturlig pausepunkt —

Noen ganger vet du ikke på forhånd hvor mange runder det blir. Du vet bare når du skal stoppe: når brukeren skriver noe gyldig, når et tall ikke lenger er delelig, når summen har passert en grense.

Da bruker du while.

`while betingelse:`

Sjekker betingelsen før hver runde, og kjører kroppen så lenge den er sann.

Er betingelsen usann allerede første gang, kjøres kroppen null ganger. Det er ingen feil — det er ofte hele poenget.

Betingelsen er nøyaktig det samme slags uttrykk som i en if fra kap. 1.2. Forskjellen er bare at den sjekkes på nytt for hver runde.

Løkketerminering

En while-løkke stopper når betingelsen blir usann. For at det skal skje, må noe i kroppen endre verdien betingelsen bygger på.

Kontrollspørsmålet du skal stille hver eneste gang du skriver eller sporer en while: hvilken variabel i betingelsen endres inne i løkka, og nærmer den seg grensen?

Vær ekstra på vakt når betingelsen bruker !=. Den krever et eksakt treff: while n != 10: med n += 3 fra 0 treffer 0, 3, 6, 9, 12 … og passerer 10 uten å stoppe.

Uendelig løkke

En løkke der betingelsen aldri blir usann. Programmet henger og må stoppes utenfra.

De to vanligste årsakene er at tellevariabelen ikke oppdateres i det hele tatt, og at oppdateringen går feil vei — n -= 1 der n skal vokse.

På eksamen er dette et gyldig sporingssvar: riktig svar kan være at programmet aldri stopper. Det er også en av de faste variantene i «fyll inn manglende kodelinje»-oppgavene, der tre av alternativene gir uendelig løkke.

`break`

Avbryter løkka umiddelbart — men bare den innerste løkka den står i. Resten av kroppen hoppes over, og programmet fortsetter på første linje etter løkka.

Står break inne i en nøstet løkke, fortsetter den ytre som om ingenting hadde skjedd. Skal du ut av begge, trenger du noe mer — for eksempel en return hvis løkkene står i en funksjon.

break er lovlig i fasit og er den naturlige måten å si «vi er ferdige, ikke se på resten».

`continue`

Hopper til neste runde og over resten av kroppen. Løkka fortsetter — det er bare denne ene runden som kuttes kort.

I en while-løkke er continue farlig: står oppdateringen av tellevariabelen etter den, blir den aldri kjørt, og løkka går for alltid. I en for-løkke er den trygg, fordi løkkevariabelen oppdateres av range og ikke av kroppen.

En løkke er ofte lettere å lese uten continue — det samme oppnås ved å snu if-testen.

✏️Eksempel 4: `while` som leter seg fram

Fra n = 12: hvor mange ganger kan tallet halveres før det blir et oddetall, og hva sitter du igjen med?

n = 12
antall = 0
while n % 2 == 0:
    n = n // 2
    antall += 1
print(n, antall)

Utskrift:

3 2

Sporing, runde for runde:

Før rundenn % 2 == 0?n etterpåantall etterpå
n = 12ja61
n = 6ja32
n = 3nei — løkka stopper32

Betingelsen sjekkes før hver runde, også den siste gangen, da den er usann og kroppen ikke kjøres.
Legg merke til at n = n // 2 bruker heltallsdeling. Med / ville n blitt et flyttall, utskriften 3.0, og hele oppgaven en annen — dette er felle #9 fra kap. 1.1.
📝Oppgave 7
Sjanger B

Hva skriver programmet ut?

n = 1
runder = 0
while n < 100:
    n = n * 3
    runder += 1
print(n, runder)

📝Oppgave 8
Eksamensnivå, sjanger B

Funksjonen skal finne det minste positive tallet som er delelig med både a og b.

def minste_felles(a, b):
    n = 1
    while n % a != 0 or n % b != 0:
        n += 1
    return n

print(minste_felles(4, 6))
print(minste_felles(3, 3))

Hva returnerer de to kallene?

📝Oppgave 9
Sjanger D

Funksjonen skal returnere summen av annethvert element i lista, fra og med det andre elementet (plassnummer 1, 3, 5 …).

def sum_annethvert(tall):
    s = 0
    for i in KODE1:
        s += tall[i]
    return s

Blokken er merket som ikke-kjørbar fordi KODE1 ikke er gyldig Python — det er plassholderen du skal fylle.

Hvilket alternativ er riktig?

a) range(0, len(tall), 2)
b) range(1, len(tall))
c) range(2, len(tall), 2)
d) range(1, len(tall), 2)

Løkke 5 — Når du trenger plassnummeret (~8 min)

Til nå har løkkene gitt deg verdien. Noen ganger trenger du å vite hvor i sekvensen du er: for å endre elementet, for å sammenligne med naboen, eller for å skrive ut et radnummer.

✏️Eksempel 5: Tre måter å gå gjennom det samme på

Ei liste med ukedagsnavn skal skrives ut med nummer foran. Vis tre framgangsmåter, og si når hver av dem passer.

Bare verdien — kortest, men uten nummer:

dager = ['mandag', 'tirsdag', 'onsdag']
for dag in dager:
    print(dag)

Utskrift:

mandag
tirsdag
onsdag

Plassnummeret, med range(len(...)) — den du trenger når elementene skal endres:

dager = ['mandag', 'tirsdag', 'onsdag']
for i in range(len(dager)):
    print(i + 1, dager[i])

Utskrift:

1 mandag
2 tirsdag
3 onsdag

Begge deler, med enumerate — den korteste når du trenger nummer og verdi samtidig:

dager = ['mandag', 'tirsdag', 'onsdag']
for i, dag in enumerate(dager):
    print(i + 1, dag)

Utskrift:

1 mandag
2 tirsdag
3 onsdag

De to siste gir identisk utskrift. Begge er tillatt i fasit, og ingen av dem er «riktigere» enn den andre — dette faget tillater snarveier og sidestiller dem med den eksplisitte varianten.

Merk i + 1 i utskriften. Plassnumrene starter på 0, men mennesker teller fra 1. Den justeringen hører hjemme i utskriften, ikke i løkka.

📝Oppgave 10
Eksamensnivå,…

Ei liste inneholder målte temperaturer time for time.

a) Skriv hoyeste(malinger) som returnerer den høyeste temperaturen, uten å bruke innebygde snarveier.
b) Skriv time_for_hoyeste(malinger) som returnerer plassnummeret til den høyeste temperaturen.
c) Hva gir de to funksjonene for lista [3, 9, 4, 9, 1]?

API- og konstruksjonsliste
Repetisjon — de sju setningene som må sitte

Dette kapitlet er skrevet av Anthropics toppmodeller (Claude Opus og Claude Fable) og er foreløpig ikke manuelt gjennomgått — kvalitetskontrollen gjøres av uavhengige KI-agenter, og innmeldte feil rettes fortløpende. Funnet en feil? Meld fra, så retter vi den. Les mer om hvordan innholdet lages.

Skolesaga er en uavhengig læringsressurs og er ikke tilknyttet eller godkjent av Norges teknisk-naturvitenskapelige universitet. Dette er ikke offisielt studiemateriell. Les mer.