Gjennomløpe med for … in
I artikkelen om for-løkker ser vi hvordan vi kan bruke range() til å tildele verdier til en løkkevariabel. Nå skal vi se at vi også kan bruke ei liste til det samme. Elementene i lista blir da én for én tildelt til løkkevariabelen når løkka gjennomløpes.
Eksempel 1 viser hvordan vi kan bruke ei liste i ei for-løkke til å skrive ut innholdet i lista demo, element for element.
Eksempel 1:
# Oppretter lista demo og skriver ut innholdet, element for element
demo = [7, -3, 8, 4, 8]
for n in demo:
print(n)
Skriv Python-kode som oppretter ei liste som inneholder alle oddetall fra og med 1 til og med 19, og skriver dem ut, ett for ett.
Av og til kan det være at vi ønsker å få nummerert elementene vi henter ut fra ei liste. Til det kan vi bruke funksjonen enumerate(). enumerate() returnerer et tallpar, der et løpenummer kommer først, deretter selve elementet.
La oss for eksempel si at vi har ei liste med primtallene under 30, og ønsker å skrive dem ut på formen Primtall nummer 1 er 2, Primtall nummer 2 er 3, og så videre. Det kan vi gjøre som vist i eksempel 2.
Eksempel 2:
# Oppretter ei liste med primtall og skriver dem ut nummerert
primliste = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
for nummer, primtall in enumerate(primliste):
print(f"Primtall nummer {nummer + 1} er {primtall}")
Grunnen til at vi skriver nummer + 1 i stedet for bare nummer, er at løpenumrene starter på 0, på samme måte som indekser. Det er imidlertid mulig å angi en startverdi for løpenummeret ved å angi teksten «start» sammen med tallet vi vil starte på. Eksempel 3 gjør det samme som eksempel 2, men angir at løpenummeret skal starte på 1, slik at vi slipper å addere 1 til nummer i utskriften.
Eksempel 3:
# Oppretter ei liste med primtall og skriver dem ut nummerert
primliste = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
for nummer, primtall in enumerate(primliste, start = 1):
print(f"Primtall nummer {nummer} er {primtall}")
Endre koden fra oppgave 1, slik at også nummeret på oddetallet skrives ut, sammen litt forklarende tekst. For eksempel Oddetall nummer 1 er 1, Oddetall nummer 2 er 3, og så videre.
Gjennomløpe med indekser
Vi kan også bruke indekser til å gjennomløpe ei liste. Vi bruker da range() til å generere de aktuelle indeksene, og refererer så til elementene i lista ved å angi indeksene i klammeparentes. Dette er illustrert i eksempel 4, som gir samme utskrift som eksempel 2 og 3.
Eksempel 4:
# Oppretter ei liste med primtall og skriver dem ut nummerert
primliste = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
for n in range(len(primliste)):
print(f"Primtall nummer {n + 1} er {primliste[n]}")
I eksempel 4 er det 10 elementer i primliste, så vi kan generere indeksene ved å skrive range(10), noe som vil gi tallene fra 0 til 9. Men da låser vi oss til at primliste inneholder 10 elementer. Dersom vi siden legger til eller fjerner elementer, vil vi måtte bytte ut 10-tallet. Det er også fort å gjøre feil hvis vi teller antall elementer i ei liste for hånd. I stedet for å angi et fast tall som argument til range(), bruker vi derfor den innebygde Python-funksjonen len(). Brukt på ei liste, returnerer len() antall elementer i lista. Hvis ei liste, a, inneholder n elementer, vil len(a) returnere n, og range(len(a)) vil gi tallene fra og med 0 til og med n − 1, som jo er indeksene i ei liste med n elementer.
Å bruke faste verdier i stedet for dynamisk genererte verdier, slik som 10 i stedet for len(), kalles hardkoding, og er generelt noe vi bør unngå, fordi det gjør koden vår mindre fleksibel.
Noen programmeringsspråk har ikke en for … in-mekanisme lik den vi har brukt i eksempel 1, 2 og 3. Da er vi nødt til å bruke indekser til gjennomløp, slik som i eksempel 4. I Python bør vi imidlertid bruke for … in når vi kan, fordi det gir enklere og mer oversiktlig kode.
Det finnes imidlertid tilfeller der å basere seg på indekser for å gjennomløpe ei liste er et riktig valg, typisk hvis vi skal referere til elementer som ikke kommer etter hverandre, eller flere elementer samtidig.
Eksempel 5 viser kode som gjennomløper ei liste for å sjekke om innholdet stemmer med Fibonaccis tallfølge, der hvert tall er lik summen av de to tallene foran. Hvis for eksempel lista fibo = [1, 1, 2, 3, 5, 8, 13], vil koden skrive ut at lista inneholder Fibonaccis følge. Men hvis fibo = [1, 1, 2, 3, 5, 8, 12], vil koden skrive ut at lista ikke inneholder Fibonaccis følge, fordi 5 + 8 ikke er 12.
Eksempel 5:
# Sjekker om lista fibo inneholder Fibonaccis tallfølge
er_fibo = True
for n in range(2, len(fibo)):
if fibo[n] != fibo[n - 1] + fibo[n - 2]:
er_fibo = False
if er_fibo == True:
print("Lista inneholder Fibonaccis følge.")
else:
print("Lista inneholder ikke Fibonaccis følge.")
Koden i eksempel 5 bruker range() til å generere n som en indeks som går fra 2 til enden av lista fibo. For hver n sjekker vi så om elementet med indeks n er lik summen av de to elementene foran, det vil si de med indeks n − 1 og n − 2. Hvis dette ikke er tilfelle, settes den boolske variabelen er_fibo til False. Hvis hele lista blir gjennomløpt uten at er_fibo, som i utgangspunktet er True, er blitt satt til False, inneholder lista Fibonaccis følge. En variabel som er_fibo, som brukes til å signalisere en tilstand, kalles et flagg.
Vi burde strengt tatt også sjekket om de to første elementene begge er 1, men vi droppet det for oversiktens skyld.
Koden i eksempel 5 kan for øvrig skrives bedre, slik det beskrives i artikkelen om break.
Endre koden fra oppgave 1 slik at den bruker indekser til å skrive ut lista med oddetallene i omvendt rekkefølge.
Hvis vi skal endre elementene ei liste mens vi gjennomløper den, må vi også bruke indekser, som i eksempel 6, der vi kvadrerer alle elementene i ei liste.
Eksempel 6:
# Kvadrerer elementene i lista demo
demo = [1, 2, 3, 4]
for n in range(len(demo)):
demo[n] **= 2
Alternativt kan vi skrive koden i eksempel 6 som i eksempel 7, der vi bruker enumerate() til å generere indeksene.
Eksempel 7:
# Kvadrerer elementene i lista demo
demo = [1, 2, 3, 4]
for n, tall in enumerate(demo):
demo[n] = tall**2
Kilder
-
- Matthes A. (2019). Python Crash Course. no starch press
Programmeringsspråket JavaScript har en mekanisme tilsvarende for … in, som heter for … of. Programmeringsspråket C har imidlertid ingen slik mekanisme. I C må vi basere oss på å generere en følge med tall og bruke disse som indekser.
Se film om lister