Bouw zelf — het bereik van een lijst
Leerdoel: je gebruikt max_en_min om een nieuwe waarde af te
leiden: het bereik (groot − klein). Dit is een veelgebruikte
statistische maat.
Opdracht
Schrijf bereik(lijst) die het verschil tussen het grootste en kleinste
element returnt.
bereik([5, 2, 8, 1, 7, 4])→7(want 8 − 1)bereik([-3, -1, -7])→6(want -1 − (-7))bereik([42])→0
De startcode roept je functie aan op vijf lijsten en print het bereik naast wat het moet zijn.
Tip
max_en_min(lijst) geeft een tuple terug. Pak hem uit met
klein, groot = max_en_min(lijst) en bereken dan het verschil.
Antwoord
def bereik(lijst):
klein, groot = max_en_min(lijst)
return groot - klein
Of zonder uitpakken:
def bereik(lijst):
return max_en_min(lijst)[1] - max_en_min(lijst)[0]
Die laatste is slechter: hij roept max_en_min twee keer aan en doet dus
dubbel werk. Uitpakken is netter.
Onderzoek
Wat gebeurt er als je bereik([]) aanroept op een lege lijst?
Probeer het maar — pas de tests-lijst aan en voeg ([], 0) toe.
Je krijgt een IndexError: list index out of range op de regel
klein = groot = lijst[0] binnen max_en_min. De functie gaat er
namelijk vanuit dat er een eerste element bestaat om mee te starten.
Dat is een afspraak over de invoer en geen bug: max_en_min werkt alleen
op lijsten met minstens één element. Wil je een lege lijst wél aankunnen,
dan checkt bereik of max_en_min daar eerst op, bijvoorbeeld met
if not lijst: return 0.
Uitdaging (optioneel)
Schrijf genormaliseerd(lijst) die elk element omrekent naar een waarde
tussen 0 en 1, op basis van het bereik:
genormaliseerd(x) = (x - klein) / (groot - klein)
Voor [1, 5, 9] → [0.0, 0.5, 1.0]. Wat gebeurt er als alle waardes
gelijk zijn? (Hint: deling door 0.)
Tip
Bereken klein, groot en het bereik één keer, vóór de lus. Loop dan
langs de lijst en voeg per element de omgerekende waarde toe aan een
nieuwe lijst. Is het bereik 0, dan zijn alle waardes gelijk; kies dan
zelf wat je teruggeeft (bijvoorbeeld overal 0.0) in plaats van te
delen.
Antwoord
def max_en_min(lijst):
klein = groot = lijst[0]
for waarde in lijst:
if waarde < klein:
klein = waarde
elif waarde > groot:
groot = waarde
return klein, groot
def genormaliseerd(lijst):
klein, groot = max_en_min(lijst)
bereik = groot - klein
resultaat = []
for x in lijst:
if bereik == 0:
resultaat.append(0.0)
else:
resultaat.append((x - klein) / bereik)
return resultaat
print(genormaliseerd([1, 5, 9])) # [0.0, 0.5, 1.0]
print(genormaliseerd([4, 4, 4])) # [0.0, 0.0, 0.0]
Zonder de check op bereik == 0 crasht [4, 4, 4] met een
ZeroDivisionError.
Door naar veelgemaakte fouten.