← Python/Idiomatisch en performance
Les 1 van 8
MODULE 13 · 01◷ 30 min

Samenhang zichtbaar maken met enumerate en zip

Na deze les kun je
  • Een positie en waarde samen verwerken zonder een losse teller.
  • Gelijke lengtes met zip(strict=True) bewaken.
  • Twee opeenvolgende waarden en gekoppelde aantallen verwerken.

Een magazijnlijst bevat namen en een tweede lijst bevat aantallen. Wanneer je beide los doorloopt, is één vergeten teller genoeg om de verkeerde bestelling te tonen. Python heeft hulpmiddelen waarmee je de samenhang rechtstreeks in de lus schrijft.

Een positie hoort bij een waarde

Idiomatisch betekent dat je een bekend taalpatroon gebruikt wanneer het de bedoeling duidelijk maakt. Dat is geen wedstrijd om zo weinig mogelijk tekens. Een leesbare lus is nuttiger dan een korte uitdrukking die je later moet ontcijferen.

Met enumerate krijg je per ronde een paar: de positie en de oorspronkelijke waarde. Het argument start bepaalt alleen het eerste nummer dat je ziet. Het slaat geen elementen uit de bron over en verandert de bron niet.

Je kent unpacking uit de collectiemodule. for number, name in enumerate(names, start=1) pakt precies zo ieder paar uit. Een aparte teller initialiseren en verhogen is dan overbodig.

Twee bronnen vormen paren

zip brengt de volgende waarde uit iedere bron samen in een tuple. De gewone vorm stopt zodra de kortste bron klaar is. Dat is handig wanneer je bewust alleen het overlappende deel wilt, maar gevaarlijk als alle gegevens bij elkaar horen.

Gebruik strict=True als gelijke lengtes een contract zijn. Een verschil levert dan tijdens het doorlopen een ValueError op. Alleen het zip-object maken is nog geen controle: zip is lui en kijkt pas verder wanneer iemand er waarden uit vraagt.

Nummeren zonder een fruitnaam over te slaan
fruit = ["peer", "kiwi", "pruim"]
labels = ["P", "K", "R"]
for number, (name, label) in enumerate(zip(fruit, labels, strict=True), start=4):
    print(f"{number}: {label} = {name}")
Verwachte uitvoer
4: P = peer
5: K = kiwi
6: R = pruim

Dit voorbeeld gebruikt andere gegevens dan de opdrachten. Er staan drie fruitnamen en drie etiketten; ieder paar wordt maar eenmaal uitgepakt. De nummers beginnen bij vier, terwijl de eerste fruitnaam gewoon behouden blijft.

Naast elkaar kijken

Met zip(values, values[1:]) koppel je bij een lijst iedere waarde aan zijn opvolger. De tweede lijst is met opzet één element korter. Hier zou strict=True dus juist een fout veroorzaken: ongelijke lengte is onderdeel van dit vensterpatroon.

Een lege lijst of één met maar één waarde heeft geen opeenvolgende paren. De uitkomst is dan een lege lijst. Voor iedere gevonden buur kun je bijvoorbeeld het verschil right - left berekenen; de volgorde van aftrekken bepaalt het teken.

Veelgemaakte fout: verdwijnen is geen bevestiging

Je koppelt drie klanten aan twee bedragen en krijgt zonder fout twee paren. De derde klant is daarmee niet gecontroleerd. Een korte uitkomst kan er keurig uitzien, terwijl je stil gegevens verloren hebt.

Gewone zip kan een ontbrekend bedrag verbergen
names = ["Ada", "Bo", "Cem"]
amounts = [5, 8]
print(list(zip(names, amounts)))
try:
    list(zip(names, amounts, strict=True))
except ValueError:
    print("Niet iedere naam heeft een bedrag.")
Verwachte uitvoer
[('Ada', 5), ('Bo', 8)]
Niet iedere naam heeft een bedrag.

De lijstvorming in dit voorbeeld verbruikt de iterator en maakt het lengteverschil zichtbaar. Een controle vóór de lus kan bij twee lijsten ook, maar werkt niet zomaar voor een iterator zonder lengte. De strikte variant controleert terwijl zij loopt.

Van patroon naar contract

De oefenfuncties ontvangen lijsten en wijzigen die niet. Bij gekoppelde lijsten moeten alle elementen aan bod komen; bij buurverschillen gebruik je alleen paren die echt bestaan. Een gewogen totaal vermenigvuldigt ieder bedrag met zijn bijbehorende aantal en telt de producten op.

Voor een lege koppeling is dat totaal nul. Een lengteverschil moet ook bij lege invoer aan één kant blijven opvallen. Geef de ValueError door, zodat de aanroeper een onvolledige bestelling kan herkennen.

AAN DE SLAG 0/4
1

Nummer en waarde samen teruggeven

Vul numbered(items, start=1) in: geef een lijst tuples met telkens nummer en waarde. Behoud iedere waarde in bronvolgorde; start is het eerste nummer, geen aantal over te slaan elementen.

2

Een volledige koppeling maken

Vul pair_rows(left, right) in: geef een lijst paren. Beide bronnen moeten dezelfde lengte hebben; geef ValueError door als één korter is.

3

Verschillen tussen buren

Vul neighbor_deltas(values) in voor een lijst getallen: geef per opeenvolgend paar right - left terug. Leeg of één element levert een lege lijst; wijzig de bron niet.

4

Bedrag en aantal combineren

Vul weighted_total(prices, quantities) in: vermenigvuldig ieder prijs-aantalpaar en tel de producten op. Lege lijsten geven 0; ongelijke lengtes geven ValueError. Wijzig beide lijsten niet.

Samenvatting

  • enumerate koppelt nummers aan waarden zonder een losse teller.
  • zip vormt paren; strict=True controleert gelijke lengtes tijdens consumptie.
  • Een buurvenster mag bewust ongelijke bronlengtes hebben.

Hierna sorteer je gegevens met een expliciete sleutel, zodat de volgorde net zo duidelijk wordt als de koppeling.

iteration_tools.py
UitvoerPython
›
›_

Hier komt je resultaat.

Voer je code uit en ontdek
wat je hebt gemaakt.

0/4 stappen
EVEN MEEKIJKEN

Bekijk hoe het kan.

Je mag de oplossing bekijken. Deze poging telt dan niet mee als afgeronde les. Met Reset kun je daarna opnieuw zelf oefenen.