Geavanceerd itereren
Contents
2.7. Geavanceerd itereren#
2.7.1. Combinatie for, if#
Naast het individuele gebruik van for, if (en elif, else), kunnen we deze speciale functionaliteit van Python ook stapelen. Kijk maar eens naar het onderstaande stukje code en de bijbehorende output.
namen = ["Albert", "Bertha", "Clara", "Dennis"]
cijfers = [5.8, 5.0, 8.2, 2.3]
for naam, cijfer in zip(namen, cijfers):
print(naam, cijfer)
if cijfer > 5.75:
print(naam, "heeft een voldoende!\n")
else:
print(naam, "heeft een onvoldoende.\n")
print("Of toch niet!?")
Albert 5.8
Albert heeft een voldoende!
Bertha 5.0
Bertha heeft een onvoldoende.
Clara 8.2
Clara heeft een voldoende!
Dennis 2.3
Dennis heeft een onvoldoende.
Of toch niet!?
Zoals je hier kunt zien gebruiken we een for-loop en de zip()-functie om tegelijkertijd door de lijsten namen en cijfers heen te lopen. Door dit tegelijkertijd te doen weten we zeker dat de variabelen naam en cijfer die tegelijk ingelezen worden ook bij elkaar horen.
Daarna wordt er binnen de for-loop gebruik gemaakt van een if-else constructie om te printen of deze persoon een voldoende heeft gehaald. Door dit binnen de for-loop te zetten wordt dit voor elke bijbehorende set van een naam en een cijfer uitgevoerd.
2.7.2. Itereren over dict#
Het itereren over de elementen die in een dict opgeslagen staat gaat net als bij lijsten.
# Op welke dagen hebben we vrije uren?
rooster = {'Maandag': [3, 4],
'Dinsdag': [1, 2],
'Woensdag': [7, 8],
'Donderdag': [],
'Vrijdag': [1, 2, 5, 6, 7, 8]}
# Print het type van de variabele 'rooster'.
# `\n' staat voor *Print verder op een de volgende regel*.
print(type(rooster))
print()
for dag in rooster:
print(dag)
<class 'dict'>
Maandag
Dinsdag
Woensdag
Donderdag
Vrijdag
Het zou natuurlijk handig zijn als we ook de waarden die bij de dagen horen kunnen gebruiken binnen de for-lus. Dit gaat als volgt. Merk op dat we nu twee variabelen voor in zetten, en dat we .items() toegevoegd hebben na de naam van de dict-variabele.
# Op welke dagen hebben we vrije uren?
rooster = {'Maandag': [3, 4],
'Dinsdag': [1, 2],
'Woensdag': [7, 8],
'Donderdag': [],
'Vrijdag': [1, 2, 5, 6, 7, 8]}
for dag, vrije_uren in rooster.items():
print('Op', dag, 'hebben we vrij op de volgende uren:', vrije_uren)
Op Maandag hebben we vrij op de volgende uren: [3, 4]
Op Dinsdag hebben we vrij op de volgende uren: [1, 2]
Op Woensdag hebben we vrij op de volgende uren: [7, 8]
Op Donderdag hebben we vrij op de volgende uren: []
Op Vrijdag hebben we vrij op de volgende uren: [1, 2, 5, 6, 7, 8]
Met .items() pakken we het dict als het ware uit. In de loop krijgen we dan telkens een combinatie van twee variabelen: de naam van het object in de dict (de key) en de waarde van dit object (de value).
.keys(), .values() of .items()?#
We kunnen in plaats van zowel de keys als de values uit een dict te halen met .items(), ook alleen de keys of alleen de values uit een dict halen.
cijferlijst = {'Henk': 5.5, 'Ingrid': 5.8}
for student in cijferlijst.keys():
print(student)
print()
for cijfer in cijferlijst.values():
print(cijfer)
print()
for student, cijfer in cijferlijst.items():
print(student, cijfer)
Henk
Ingrid
5.5
5.8
Henk 5.5
Ingrid 5.8
De oplettende lezer ziet dat .keys() eigenlijk niets toevoegt - we krijgen hetzelfde gedrag als wanneer we niks achter cijferlijst zetten.
2.7.3. Voorbeelden#
We sluiten deze module af met een voorbeelden die de meeste van de eerder behandelde acties combineren.
werknemer_1 = {'naam': 'Alice', 'gewerkte_uren': [4,2,5,6,8], 'uurloon': 13.50, 'salaris': 0.0}
werknemer_2 = {'naam': 'Bertha', 'gewerkte_uren': [6,1,7,2,1], 'uurloon': 15.50, 'salaris': 0.0}
werknemer_3 = {'naam': 'Claudia', 'gewerkte_uren': [2,3,5,3,5], 'uurloon': 25.50, 'salaris': 0.0}
werknemers = [werknemer_1, werknemer_2, werknemer_3]
for werknemer in werknemers:
uurloon_werknemer = werknemer['uurloon']
gewerkte_uren_werknemer = werknemer['gewerkte_uren']
for uren in gewerkte_uren_werknemer:
werknemer['salaris'] = werknemer['salaris'] + uren * uurloon_werknemer
print(werknemer['naam'], 'heeft', werknemer['salaris'], 'euro verdiend.')
print(werknemers)
Alice heeft 337.5 euro verdiend.
Bertha heeft 263.5 euro verdiend.
Claudia heeft 459.0 euro verdiend.
[{'naam': 'Alice', 'gewerkte_uren': [4, 2, 5, 6, 8], 'uurloon': 13.5, 'salaris': 337.5}, {'naam': 'Bertha', 'gewerkte_uren': [6, 1, 7, 2, 1], 'uurloon': 15.5, 'salaris': 263.5}, {'naam': 'Claudia', 'gewerkte_uren': [2, 3, 5, 3, 5], 'uurloon': 25.5, 'salaris': 459.0}]
We kunnen dit iets efficienter opschrijven, door wat hulpvariabelen over te slaan:
werknemers = [{'naam': 'Alice', 'gewerkte_uren': [4,2,5,6,8], 'uurloon': 13.50, 'salaris': 0.0},
{'naam': 'Bertha', 'gewerkte_uren': [6,1,7,2,1], 'uurloon': 15.50, 'salaris': 0.0},
{'naam': 'Claudia', 'gewerkte_uren': [2,3,5,3,5], 'uurloon': 25.50, 'salaris': 0.0} ]
for werknemer in werknemers:
for uren in werknemer['gewerkte_uren']:
werknemer['salaris'] += uren * werknemer['uurloon']
print(werknemer['naam'], 'heeft', werknemer['salaris'], 'euro verdiend.')
print(werknemers)
Alice heeft 337.5 euro verdiend.
Bertha heeft 263.5 euro verdiend.
Claudia heeft 459.0 euro verdiend.
[{'naam': 'Alice', 'gewerkte_uren': [4, 2, 5, 6, 8], 'uurloon': 13.5, 'salaris': 337.5}, {'naam': 'Bertha', 'gewerkte_uren': [6, 1, 7, 2, 1], 'uurloon': 15.5, 'salaris': 263.5}, {'naam': 'Claudia', 'gewerkte_uren': [2, 3, 5, 3, 5], 'uurloon': 25.5, 'salaris': 459.0}]
In je ontwerpproject moet je verschillende concepten met elkaar vergelijken, waarbij je ze deelscores geeft voor bepaalde factoren (ieder met een eigen wegingsfactor). Dit kun je automatiseren door bijvoorbeeld het onderstaande stukje code te schrijven.
"""
Dit script vergelijkt verschillende manieren om een stapel papier netjes bij elkaar te houden.
Deze manieren worden vergeleken aan de hand van gewogen scores voor prestatiefatoren.
"""
factoren = {'max. aantal blaadjes': 0.3,
'houdt papier netjes': 0.5,
'aantal stuks per euro': 0.2}
concepten = {'paperclip': [5, 10, 7],
'nietje': [6, 9, 9],
'elastiek': [9, -2, 7]}
gewogen_scores = {}
for concept_naam, concept_scores in concepten.items():
print('We gaan de score berekenen van het concept', concept_naam, '.\n')
gewogen_scores[concept_naam] = 0
for concept_score, (factor_naam, factor_gewicht) in zip(concept_scores, factoren.items()):
if concept_score < 0:
print('Pas op:', concept_naam, 'heeft een negatieve deelscore voor de factor', factor_naam, '.')
print('Concept', concept_naam, 'scoort voor', factor_naam, concept_score, 'punten, met gewicht', factor_gewicht, '.')
gewogen_scores[concept_naam] = gewogen_scores[concept_naam] + factor_gewicht * concept_score
print('Tussenstand: ', gewogen_scores[concept_naam], '\n')
print('Gewogen score voor', concept_naam, ':', gewogen_scores[concept_naam], '\n\n')
We gaan de score berekenen van het concept paperclip .
Concept paperclip scoort voor max. aantal blaadjes 5 punten, met gewicht 0.3 .
Tussenstand: 1.5
Concept paperclip scoort voor houdt papier netjes 10 punten, met gewicht 0.5 .
Tussenstand: 6.5
Concept paperclip scoort voor aantal stuks per euro 7 punten, met gewicht 0.2 .
Tussenstand: 7.9
Gewogen score voor paperclip : 7.9
We gaan de score berekenen van het concept nietje .
Concept nietje scoort voor max. aantal blaadjes 6 punten, met gewicht 0.3 .
Tussenstand: 1.7999999999999998
Concept nietje scoort voor houdt papier netjes 9 punten, met gewicht 0.5 .
Tussenstand: 6.3
Concept nietje scoort voor aantal stuks per euro 9 punten, met gewicht 0.2 .
Tussenstand: 8.1
Gewogen score voor nietje : 8.1
We gaan de score berekenen van het concept elastiek .
Concept elastiek scoort voor max. aantal blaadjes 9 punten, met gewicht 0.3 .
Tussenstand: 2.6999999999999997
Pas op: elastiek heeft een negatieve deelscore voor de factor houdt papier netjes .
Concept elastiek scoort voor houdt papier netjes -2 punten, met gewicht 0.5 .
Tussenstand: 1.6999999999999997
Concept elastiek scoort voor aantal stuks per euro 7 punten, met gewicht 0.2 .
Tussenstand: 3.0999999999999996
Gewogen score voor elastiek : 3.0999999999999996
Bestudeer deze voorbeeldcode en kijk daarna of je de vragen in de bijbehorende opgave kunt beantwoorden.