5. Selektion
Under körningen av ett program görs många val som bestämmer vilken väg programmet ska ta genom koden. Varje sådant val kallas för en selektion. I Python ser vi främst selektion i form av if-satser som beräknar värdet av ett villkor och sedan gör olika saker beroende på om villkoret var sant eller falskt. I det här kapitlet ska vi fördjupa oss lite mer i if-satsen.
1. Vad räknas som sant och falskt?
Vi har tidigare introducerat de två grundläggande sanningsvärdena True
och False
. Men vad händer om ett villkor beräknas till något annat? Python har en strategi för vad som räknas som sant respektive falskt:
Räknas som sant | Räknas som falskt |
---|---|
True |
False |
Alla tal som inte är noll (ex. 1, -44.2) | Alla tal som är noll (ex. 0, 0.0) |
Alla icke-tomma strukturer (ex. [1, 2, 3], "hej") | Alla tomma strukturer (ex. [], "", {}) |
... | Det speciella objektet None |
Jämförelseoperatorer, t.ex. <
och >=
, liksom många inbyggda testfunktioner i Python returnerar alltid True
eller False
. Egentligen är True
och False
konstanter med värdena 1 och 0, men en stark rekommendation är att så långt som möjligt använda True
och False
i stället för att lita för mycket på tabellen ovan. När du använder icke-explicita sanningsvärden minskar läsbarbeten.
2. Hur kan villkorsuttryck utformas?
Schematiskt ser en enkel if-sats ut så här:
if villkorsuttryck:
programkod som körs om villkoret är sant
Villkorsuttryck kan utformas på många olika sätt:
- Literal, alltså ett tal, en sträng eller ett annat dataobjekt som tolkas som sant eller falskt (vilket ofta skapar svårläst kod)
- Operator som kombinerar två eller fler deluttryck, ofta en jämförelse, t.ex.
a < b
- Boolesk operator som kombinerar ett eller fler deluttryck, t.ex.
a < b and x == 7
- Funktions- eller metodanrop, t.ex.
isinstance(seq, list)
som testar om variablenseq
är av typen lista
3. Hur beräknas booleska operatorer?
Boolesk algebra handlar om hur man räknar med sanningsvärden. Som vi redan har nämnt är detta uppkallat efter den brittiske matematikern George Boole. De tre vanligaste operatorerna inom boolesk algebra är not, and och or. Definitionen av dessa framgår av nedanstående tabell.
a | b | not a | a and b | a or b |
---|---|---|---|---|
False | False | True | False | False |
False | True | True | False | True |
True | False | False | False | True |
True | True | False | True | True |
Förutom den här tabellen behöver du också känna till lite om hur de booleska operatorerna beräknas.
not a
innebär att uttrycketa
beräknas. Om detta är sant returnerasFalse
, annarsTrue
.a and b
innebär att uttrycketa
beräknas. Om det är falskt returneras resultatet ava
annars beräknasb
och dess resultat returneras.a or b
innebär att uttrycketa
beräknas. Om det är sant returneras resultatet ava
, annars beräknasb
och dess resultat returneras.
Både and och or använder sig alltså av så kallade kortslutande beräkningar som enbart beräknar så mycket som behövs för att kunna säga något om hela resultatet. Det innebär bland annat att vi kan använda följande strategi för tilldelning.
# a ges värdet av s, eller "default" om s är tom
= s or "default" a
Om s
är ett mer komplicerat uttryck, där vi inte är helt säkra på att det kommer returnera något vettigt, så kan vi ta det säkra före det osäkra på det här sättet.
Prioriteringsordningen för de booleska operationerna är:
- not
- and
- or
Det innebär att dessa två uttryck blir samma sak:
or not b and c a
or ((not b) and c)) (a
Trots ordningen kan det i många fall vara en bra idé att sätta ut parenteser även om de egentligen inte behövs, då det kan öka läsbarheten.
4. Satsen if som uttryck
Vi har tidigare sett att if-satser kan användas för att styra programexekveringen, det vill säga utföra olika instruktioner baserat på ett villkor. Men om man vill utföra enklare tester inne i ett uttryck kan man använda ett if-uttryck. Det fungerar som en enkel if-sats, men skrivs på bara en rad och fungerar som ett uttryck, det vill säga det returnerar ett värde.
Formatet för if-uttrycket är:
case1 if condition else case2
Exempel på användning:
= "positive" if a > 0 else "non-positive" sign
Observera att if-uttryck inte kan innehålla elif utan finns endast på formen som beskrevs ovan, else måste alltså alltid vara med.
5. Hur bör man arrangera villkoren i en if-sats?
Här kommer några bra tips på hur man kan tänka när man ska skriva en lite mer komplicerad if-sats:
- Använd inte en if-sats överhuvudtaget om du kan beräkna eller slå upp resultatet.
- Arrangera villkoren i en logisk ordning så att du lätt kan se att alla falls täcks upp (t.ex. nummerordning, bokstavsordning, från specifikt till allmänt).
- Undvik villkor som överlappar varandra.
- För tester i rekursiva funktioner (vilket vi återkommer till senare), börja alltid med basfallet.
- I sällsynta fall kan du arrangera villkoren så att det mest troliga fallet är först, för att optimera koden, men i den här kursen är läsbarhet alltid viktigare än effektivitet.
- Undvik komplicerade nästlade if-satser i flera nivåer, om det inte gör koden tydligare.
Exempel
Den första versionen av quarter är överskådlig och har alternativen i en logisk ordning, men det är onödigt många villkorssatser. Den andra versionen är bättre, eftersom vi lika gärna kan räkna fram resultatet.
def quarter(month):
""" Returns the quarter of the given month """
if 1 <= month <= 3:
return 1
elif 4 <= month <= 6:
return 2
elif 7 <= month <= 9:
return 3
elif 10 <= month <= 12:
return 4
def quarter(month):
""" Returns the quarter of the given month """
return (month - 1) // 3 + 1
Den första versionen av month nedan är överskådlig, men det är onödigt många villkorssatser. Det är lättare att kontrollera att den andra versionen korrekt, eftersom vi inte behöver kontrollera att alla index (n-värden) är korrekta utan bara ordningen i listan över månadsnamn. Även här kunde vi beräkna värdet i stället för att använda en if-sats.
def month(n):
""" Returns the name of the given month """
if n == 1:
return "January"
elif n == 2:
return "February"
elif n == 3:
return "March"
elif n == 4:
return "April"
elif n == 5:
return "May"
elif n == 6:
return "June"
elif n == 7:
return "July"
elif n == 8:
return "August"
elif n == 9:
return "September"
elif n == 10:
return "October"
elif n == 11:
return "November"
elif n == 12:
return "December"
def month(n):
""" Returns the name of the given month """
= ["January", "February", "March", "April",
names "May", "June", "July", "August", "September",
"October", "November", "December"]
return names[n - 1]
Sammanfattning
- Utöver
True
ochFalse
kan Python tolka nästan vad som helst som sant eller falskt, men koden kan bli svårläst om vi förlitar oss på detta. - Villkorsuttryck kan utformas på många olika sätt: som literaler, med operatorer eller som funktionsanrop.
- De booleska operatorerna and och or använder kortslutande beräkningar.
- Satsen if har även en kompakt variant som uttryck.
- Villkoren i en if-sats bör arrangeras i en logisk ordning.
Extramaterial
Sidansvarig: Peter Dalenius
Senast uppdaterad: 2025-04-22