Løkker

Hjelp, programmet mitt avsluttes ikke! For å avbryte en evig løkke, trykk ctrl + c når fokuset er på terminalen hvor koden kjøres.


While-løkker

For å utføre en blokk med kode flere ganger, kan man benytte en while-løkke. Koden inne i løkken utføres så lenge betingelsen evaluerer til True.

x = 0
while x < 5:
    print('Jeg snill', x)
    x += 1

print('Ferdig!')
Flytdiagram for koden over

En iterasjon er en gjennomkjøring av kodeblokken inni en løkke. I eksempelet over utføres koden fem ganger, og vi sier at løkken har fem iterasjoner.

While-løkker er spesielt godt egnet for tilfeller der vi ønsker å gjenta en sekvens med operasjoner, men vi vet ikke på forhånd hvor mange ganger. For eksempel kan vi ønske å finne det minste heltallet \(n\) slik at \(n^2\) er større enn 1000. Ved hjelp av en løkke kan vi prøve alle mulige positive heltall helt til vi finner det vi leter etter:

n = 1
while n * n <= 1000:
    n += 1
print(n, 'er laveste heltall slik at n^2 er større enn 1000')

Et irriterende program.1

name = ''
while name != 'your name':
    print('Please type your name.')
    name = input()
print('Thank you!')

Et program for å telle antall siffer i et tall.

x = 222222

part_of_x = abs(x)
count = 0

while part_of_x > 0:
    count += 1
    part_of_x = part_of_x // 10

print(f'Det er {count} siffer i {x}.')
Uendelig løkke

Når man skriver en while-løkke, kan man risikere at løkken varer evig dersom betingelsen alltid blir tilfredsstilt.

x = 1
while x < 10:
    print(x)
    x + 1     # Glemt tilordning; variabelen (x) endres ikke

For å avbryte en evig løkke, trykk ctrl + c når fokuset er på terminalen hvor koden kjøres.

Break

Break kan benyttes for å bryte ut av en løkke umiddelbart.

x = 0
while True:
    print('Jeg snill', x)
    x += 1
    if x >= 5:
        break
    print('...') # kjøres ikke siste iterasjon
print('Ferdig!')
Flytdiagram for programmet over

Et irriterende program (som tidligere), skrevet med break i stedet for en betingelse:

while True:
    print('Please type your name.')
    name = input()
    if name == 'your name':
        break
print('Thank you!')

Mange nybegynnere syntes det er lettere å forstå kombinasjonen av while True og break (som vist over) enn andre typer løkker. Denne måten å skrive løkker på er svært fleksibel, og er en fin strategi for å bli vant til å skrive løkker. En while-løkke med en betingelse er imidlertid mer kompakt, og kommuniserer ofte tydeligere hvilke omstendigheter som gjør at løkken kjøres eller termineres.

Continue

Continue benyttes for å hoppe over resten av kodeblokken i løkken og gå direkte tilbake til begynnelsen (neste steg blir å sjekke betingelsen på nytt).

x = 0
while x < 5:
    print('Jeg snill', x)
    x += 1
    if x <= 2:
        continue
    print('...') # hoppes over når x <= 2
print('Ferdig!')
Flytdiagram for programmet over

Eksempel med både break og continue:

while True:
    print("Brukernavn: ", end="")
    username = input()

    if username == "":
        break # Avbryter løkken

    if username != "admin":
        print(f"Fant ikke bruker {username}")
        continue # Avbryter resten av iterasjonen

    print(f"Passord for {username}: ", end="")
    password = input()
    if password == "42":
        print("Du er nå logget inn")
        print("Bla bla bla")
        print("Du er nå logget ut igjen")

print("Slår av maskinen nå.")
For-løkker over range

Det er ofte at vi vet før løkken starter hvor mange ganger vi ønsker at løkken skal kjøres (f. eks. om vi har en variabel som inneholder dette). Da bør vi benytte en for-løkke over en range – også kalt en «vanlig» for-løkke. En for-løkke er kortere å skrive enn en while-løkke, og reduserer faren for feil og bugs.

For-løkke over range:

for i in range(5):
    print('Jeg snill', i)

 
print('Ferdig!')

Til sammenligning: while-løkke.

i = 0
while i < 5:
    print('Jeg snill', i)
    i += 1
print('Ferdig!')
Flytdiagram for for-løkken over

Legg merke til at vi i for-løkken ikke trenger å opprette en variabel i på en egen linje før løkken starter. Variabelen i blir i stedet automatisk opprettet av for-løkken. Denne variabelen kalles en iterand (eller iterasjonsvariabel). Vi kan gi iteranden hvilket navn vi selv ønsker (etter samme regler som andre variabelnavn).

I hver iterasjon av løkken får iteranden en ny verdi hentet fra range-objektet. I eksempelet over:

  • første gang løkken kjøres, får iteranden i verdien 0,
  • andre gang løkken kjøres, får iteranden i verdien 1,
  • tredje gang løkken kjøres, får iteranden i verdien 2,
  • og så videre.

Den femte og siste gangen løkken kjøres i eksempelet over, får iteranden i verdien 4. Etter dette avsluttes løkken, fordi iteranden har nådd slutten av range-objektet.

En range i Python tilsvarer det vi i matematikken kaller en endelig aritmetisk følge: altså en endelig sekvens med tall som starter på et gitt tall, og øker med en fast verdi for hvert ledd. For eksempel er \(2, 5, 8, 11, 14, 17\) en endelig aritmetisk følge med startverdi 2 og økning 3. I Python kan vi skrive denne følgen som range(2, 20, 3).

Med for-løkke over range:

for x in range(2, 20, 3):
    print(x)

 

Til sammenligning: while-løkke.

x = 2
while x < 20:
    print(x)
    x += 3

En range kan opprettes med både ett, to og tre argumenter.

  • Ett argument: startverdi er 0, sluttverdi er det gitte argumentet, og økningen er 1. For eksempel er range(4) det samme som range(0, 4, 1), og gir følgen \(0, 1, 2, 3\).
  • To argumenter: startverdi er det første argumentet, sluttverdi er det andre argumentet, og økningen er 1. For eksempel er range(2, 5) det samme som range(2, 5, 1), og gir følgen \(2, 3, 4\).
  • Tre argumenter: startverdi er det første argumentet, sluttverdi er det andre argumentet, og økningen er det tredje argumentet. For eksempel er range(2, 20, 3) en følge med startverdi 2, sluttverdi 20, og økning 3. Denne følgen er \(2, 5, 8, 11, 14, 17\).

Eksempel: skriv ut alle tallene mellom a og b (inklusiv både a og b).

Med for-løkke over range:

a = 3
b = 10

for i in range(a, b + 1):
    print(i)

 

Til sammenligning: while-løkke.

a = 3
b = 10

i = a
while i <= b:
    print(i)
    i += 1

Eksempel: negativ økning.

# Hopp kan også være negativ. 
# Eksempel: 10 9 8 7 6
for i in range(10, 5, -1):
    print(i, end=" ")
print()

Eksempel: en range kan være tom

for i in range(0):
    print(i, end=" ")
print("---")

for i in range(-4):
    print(i, end=" ")
print("---")

for i in range(3, 3):
    print(i, end=" ")
print("---")

for i in range(19, 3):
    print(i, end=" ")
print("---")

for i in range(5, 10, -1):
    print(i, end=" ")
print("---")

En range er en samling med tall. En streng er en samling med bokstaver. En for-løkke kan brukes for å iterere over alle typer samlinger – altså både strenger, ranges, lister eller en annen type samling.

s = "foo"
for letter in s:
    print(letter)
print()

for x in ["en", "liste", "med", "strenger"]:
    print(x)
print()
Nøstede løkker
# Vi kan ha løkker inni løkker
rows = 3
cols = 5

for row in range(rows):
    for col in range(cols):
        print(f"({row}, {col})", end=" ")
    print()
# Hvilken figur tegner vi her?
height = 5

for row in range(height):
    for col in range(row):
        print("*", end="")
    print()
Stil

Benytt alltid en for-løkke hvis det er naturlig. Dette gjør det lettere å forstå koden, og er mindre utsatt for bugs som gjør at programmet blir sittende fast i en uendelig løkke.

# Dårlig
repetitions = 5
x = 0
while x < repetitions:
    print("Jeg skal være snill", x)
    x += 1
# Bra
repetitions = 5
for x in range(repetitions):
    print("Jeg skal være snill", x)

    

  1. Fra Automate the Boring Stuff with Python. Al Sweigart, CC BY-NC-SA 3.0. ↩︎