Ga naar hoofdinhoud

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.

Python
Code-omgeving wordt voorbereid…
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.