Cursus
Dictionary’s (of dict in Python) zijn een manier om elementen op te slaan, net zoals in een Python-lijst. Maar in plaats van elementen op index te benaderen, ken je er een vaste sleutel aan toe en haal je het element op met die sleutel. Je werkt dus met een "sleutel-waarde"-paar, wat voor veel problemen geschikter is dan een eenvoudige lijst. Bij data science werk je vaak met dictionary’s, dus dictionary comprehension is een vaardigheid die je onder de knie wilt krijgen.
In deze tutorial:
- Eerst zie je wat een Python-dictionary precies is en hoe je die effectief gebruikt.
- Vervolgens leer je over Python dictionary comprehensions: wat het is, waarom het belangrijk is en hoe het kan dienen als alternatief voor for-loops en lambda-functies.
- Je leert hoe je voorwaarden toevoegt aan dictionary comprehensions: je werkt met if-voorwaarden, meerdere if-voorwaarden en ook if-else-constructies.
- Tot slot zie je wat geneste dictionary comprehension is, hoe je het gebruikt en hoe je het eventueel met for-loops kunt herschrijven.
Om alle voorbeeldcode in deze tutorial zelf eenvoudig uit te voeren, kun je gratis een DataLab-werkboek aanmaken met vooraf geïnstalleerde Python en alle codevoorbeelden. Voor meer oefening met dictionary comprehension, bekijk onze interactieve cursus Python Toolbox.
Wat is een Python-dictionary?
Een dictionary in Python is een verzameling items die je benadert met een specifieke sleutel in plaats van met een index. Wat betekent dat?
Denk aan een woordenboek in de echte wereld. Als je de betekenis van een woord zoekt, gebruik je het woord zelf en niet de mogelijke index van het woord. Python-dictionary’s werken hetzelfde: het woord waarvan je de betekenis zoekt is de sleutel, en de betekenis van het woord is de waarde. Je hoeft de index van het woord in een woordenboek niet te kennen om de betekenis te vinden.
Een dictionary initialiseren in Python
Je kunt een dictionary in Python als volgt initialiseren:
a = {'apple': 'fruit', 'beetroot': 'vegetable', 'cake': 'dessert'}
a['doughnut'] = 'snack'
print(a['apple'])
fruit
print(a[0])
--------------------------------------------------------------------------- KeyError Traceback (most recent call last) <ipython-input-9-00d4a978143a> in <module>() ----> 1 print(a[0]) KeyError: 0
Eerst maken we een dictionary met de naam a met drie sleutel-waardeparen: 'apple': 'fruit', 'beetroot': 'vegetable' en 'cake': 'dessert'. De sleutels zijn strings die de namen van items voorstellen en de waarden zijn strings die het type of de categorie van het item aangeven.
Vervolgens voegen we een nieuw sleutel-waardepaar toe aan de dictionary a met de syntaxe a ['doughnut'] = 'snack'. Dit voegt de sleutel 'doughnut' toe met de bijbehorende waarde 'snack'.
De derde regel van de code print de waarde die hoort bij de sleutel 'apple' in de dictionary a. Omdat 'apple' een sleutel in de dictionary is, print de code de waarde 'fruit'.
De vierde regel probeert de waarde te printen die hoort bij de sleutel 0 in de dictionary a, maar dat is geen geldige sleutel. Dit resulteert in een KeyError, die wordt opgegooid wanneer je een sleutel probeert te benaderen die niet bestaat.
Datatypen in Python-dictionary’s
De items in een dictionary kunnen elk datatype hebben. Bekijk hieronder nog wat voorbeelden van een dictionary om gevoel te krijgen voor het concept:
Maak een dictionary a met vier sleutel-waardeparen:
a = {'one': 1, 'two': 'to', 'three': 3.0, 'four': [4,4.0]}
print(a)
Werk de waarde bij die hoort bij de sleutel 'one' in de dictionary a naar 1.0.
# Update a dictionary
a['one'] = 1.0
print(a)
{'four': [4, 4.0], 'two': 'to', 'three': 3.0, 'one': 1.0}
Verwijder het sleutel-waardepaar dat hoort bij de sleutel 'one' uit de dictionary a.
# Delete a single element
del a['one']
print(a)
{'four': [4, 4.0], 'two': 'to', 'three': 3.0}
Verwijder alle sleutel-waardeparen uit de dictionary a met de methode clear().
# Delete all elements in the dictionary
a.clear()
print(a)
{}
Verwijder de dictionary a met het sleutelwoord del.
# Delete the dictionary
del a
print(a)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-12-701c9d6596da> in <module>()
1 del a #Deletes the dictionary
----> 2 print(a)
NameError: name 'a' is not defined
Het is belangrijk te onthouden dat een sleutel uniek moet zijn in een dictionary; dubbele sleutels zijn niet toegestaan. Bij dubbele sleutels geeft Python echter geen foutmelding: de laatste instantie van de sleutel is leidend en het eerste sleutel-waardepaar wordt genegeerd. Zie zelf:
sweet_dict = {'a1': 'cake', 'a2':'cookie', 'a1': 'icecream'}
print(sweet_dict['a1'])
icecream
Python Dictionary Comprehension
Dictionary comprehension is een methode om de ene dictionary om te vormen naar een andere. Tijdens deze transformatie kunnen items uit de oorspronkelijke dictionary conditioneel worden opgenomen in de nieuwe dictionary en kan elk item waar nodig worden getransformeerd.
Een goede comprehension maakt je code expressiever en daardoor makkelijker leesbaar. De sleutel bij het maken van comprehensions is te voorkomen dat ze zo complex worden dat je hoofdpijn krijgt van het ontcijferen wat ze eigenlijk doen. Houd het uitgangspunt "makkelijk te lezen" in leven.
Dictionary comprehension in Python werkt doordat je toegang hebt tot de key-objecten en de value-objecten van een dictionary.
Hoe doe je dat?
Python helpt je hierbij! Je kunt simpelweg de ingebouwde methodes gebruiken:
dict1 = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
# Put all keys of `dict1` in a list and returns the list
dict1.keys()
dict_keys(['c', 'd', 'a', 'b'])
# Put all values saved in `dict1` in a list and returns the list
dict1.values()
dict_values([3, 4, 1, 2])
De code hierboven maakt een Python-dictionary dict1 met vier sleutel-waardeparen. De methode keys() wordt op de dictionary aangeroepen en geeft een view-object terug met alle sleutels in de dictionary.
De methode values() wordt ook aangeroepen en geeft een view-object terug met alle waarden in de dictionary.
Beide view-objecten gedragen zich als sets en kunnen worden gebruikt om set-operaties uit te voeren op respectievelijk de sleutels en de waarden.
Merk op dat de volgorde van de sleutels en waarden in de view-objecten niet gegarandeerd dezelfde is als de volgorde waarin ze aan de dictionary zijn toegevoegd.
Eenvoudige waardetransformatie
Beginnen we met een eenvoudige dictionary comprehension:
dict1 = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
# Double each value in the dictionary
double_dict1 = {k:v*2 for (k,v) in dict1.items()}
print(double_dict1)
{'e': 10, 'a': 2, 'c': 6, 'b': 4, 'd': 8}
In de comprehension hierboven maken we een nieuwe dictionary double_dict1 op basis van dict1 door simpelweg elke waarde te verdubbelen.
Je kunt ook de sleutels aanpassen. Laten we bijvoorbeeld dezelfde dictionary maken, maar ook de namen van de sleutels veranderen.
dict1_keys = {k*2:v for (k,v) in dict1.items()}
print(dict1_keys)
{'dd': 4, 'ee': 5, 'aa': 1, 'bb': 2, 'cc': 3}
De methode items() gebruiken
Nu je weet hoe je alle sleutels en waarden in een dictionary benadert, kun je ook elk sleutel-waardepaar benaderen met de methode items():
dict1.items()
dict_items([('c', 3), ('d', 4), ('a', 1), ('b', 2)])
Dit is het algemene sjabloon dat je kunt volgen voor dictionary comprehension in Python:
dict_variable = {key:value for (key,value) in dictonary.items()}
Dit kan dienen als het basis- en simpelste sjabloon. Het kan steeds complexer worden naarmate je voorwaarden toevoegt.
De methode fromkeys() gebruiken
Python biedt ook de methode fromkeys(), waarmee je dictionaries kunt maken met een uniforme waarde voor een opgegeven set sleutels. Dit is handig bij het initialiseren van dictionary’s met standaardwaarden. Kijk maar:
# Create a dictionary with keys ranging from 0 to 4, all set to True
my_dict = dict.fromkeys(range(5), True)
print(my_dict)
{0: True, 1: True, 2: True, 3: True, 4: True}
In dit voorbeeld maakt fromkeys() een dictionary waarin de sleutels de getallen 0 t/m 4 zijn en elke sleutel de waarde True krijgt. Deze aanpak vereenvoudigt taken zoals het initialiseren van dictionary’s voor latere updates of verwerking.
Waarom dictionary comprehension gebruiken?
Dictionary comprehension is een krachtig concept en kan for-loops en lambda-functies vervangen. Niet alle for-loops kun je als dictionary comprehension schrijven, maar elke dictionary comprehension is wel met een for-loop te schrijven.
Neem het volgende probleem: je wilt een nieuwe dictionary maken waarbij de sleutel een getal is dat deelbaar is door 2 in het bereik 0–10, en de waarde het kwadraat van dat getal.
Zo los je hetzelfde probleem op met een for-loop en met dictionary comprehension:
numbers = range(10)
new_dict_for = {}
# Add values to `new_dict` using for loop
for n in numbers:
if n%2==0:
new_dict_for[n] = n**2
print(new_dict_for)
{0: 0, 8: 64, 2: 4, 4: 16, 6: 36}
# Use dictionary comprehension
new_dict_comp = {n:n**2 for n in numbers if n%2 == 0}
print(new_dict_comp)
{0: 0, 8: 64, 2: 4, 4: 16, 6: 36}
Alternatief voor for-loops
For-loops worden gebruikt om een bepaalde bewerking of instructieblok een opgegeven aantal keren te herhalen. Maar geneste for-loops (een for-loop binnen een for-loop) kunnen verwarrend en complex worden. In zulke situaties zijn dictionary comprehensions beter en vereenvoudigen ze de leesbaarheid en je begrip van de code.
Tip: bekijk DataCamp’s tutorial Loops in Python voor meer informatie over loops in Python.
Alternatief voor lambda-functies
Lambda-functies zijn een manier om kleine anonieme functies te maken. Het zijn functies zonder naam. Dit zijn wegwerpfuncties die alleen nodig zijn waar ze zijn gemaakt. Lambda-functies worden vooral gebruikt in combinatie met de functies filter(), map() en reduce().
Kijken we naar de lambda-functie samen met de functie map():
# Initialize `fahrenheit` dictionary
fahrenheit = {'t1':-30, 't2':-20, 't3':-10, 't4':0}
#Get the corresponding `celsius` values
celsius = list(map(lambda x: (float(5)/9)*(x-32), fahrenheit.values()))
#Create the `celsius` dictionary
celsius_dict = dict(zip(fahrenheit.keys(), celsius))
print(celsius_dict)
{'t2': -28.88888888888889, 't3': -23.333333333333336, 't1': -34.44444444444444, 't4': -17.77777777777778}
Een uitgebreid voorbeeld van Python dictionary comprehension
Laten we nog een situatie bekijken waarin je een dictionary met Fahrenheit-temperaturen wilt omzetten naar Celsius.
We breken de code op: eerst definieer je een wiskundige formule die de conversie van Fahrenheit naar Celsius doet.
In de code gebeurt dit met behulp van de lambda-functie. Je geeft die functie vervolgens door als argument aan de functie map(), die de bewerking toepast op elk item in de lijst fahrenheit.values().
Weet je nog, de functie values()? Die geeft een lijst terug met de items die in de dictionary zijn opgeslagen.
Wat je nu hebt is een lijst met temperatuurwaarden in Celsius, maar de oplossing vereist een dictionary.
Python heeft een ingebouwde functie zip() die over de elementen van iterators loopt en ze aggregeert. Je kunt meer lezen over de functie zip() in dit Python-voorbeeld.
In ons voorbeeld hierboven aggregeert zip de items uit fahrenheit.keys() en de lijst celsius, zodat je een sleutel-waardepaar krijgt dat je met de functie dict kunt samenvoegen tot een dictionary, wat het gewenste resultaat is.
Laten we nu hetzelfde probleem oplossen met dictionary comprehension:
# Initialize the `fahrenheit` dictionary
fahrenheit = {'t1': -30,'t2': -20,'t3': -10,'t4': 0}
# Get the corresponding `celsius` values and create the new dictionary
celsius = {k:(float(5)/9)*(v-32) for (k,v) in fahrenheit.items()}
print(celsius_dict)
{'t2': -28.88888888888889, 't3': -23.333333333333336, 't1': -34.44444444444444, 't4': -17.77777777777778}
Hier is een uitleg van wat we hierboven hebben gemaakt:
-
Maak een dictionary
fahrenheitmet vier sleutel-waardeparen die temperatuurmetingen in Fahrenheit voorstellen. -
Definieer een nieuwe dictionary
celsius. -
Gebruik een dictionary comprehension om over de dictionary
fahrenheitte itereren en de Fahrenheit-temperaturen om te rekenen naar Celsius met de formule(5/9) * (F-32). -
Voor elk sleutel-waardepaar in
fahrenheitwordt de sleutel toegewezen aan variabeleken de waarde aan variabelev. -
De bijbehorende Celsius-waarde wordt met bovenstaande formule berekend en als sleutel-waardepaar toegevoegd aan de dictionary
celsius. -
De resulterende dictionary
celsiuswordt geprint naar de console.
Zoals je ziet, kun je het probleem met één regel code oplossen met dictionary comprehension, in plaats van het tweestappenproces waarbij je bovendien drie functies (lambda, map() en zip()) moet begrijpen in de eerste implementatie.
Bovendien is de oplossing met dictionary comprehension intuïtief en makkelijk te begrijpen. Daarom kan dictionary comprehension goed dienen als alternatief voor lambda-functies.
Voorwaarden toevoegen aan dictionary comprehension
Vaak moet je bij het oplossen van problemen voorwaarden toevoegen. Laten we bekijken hoe je voorwaarden toevoegt aan dictionary comprehension om het krachtiger te maken.
If-voorwaarde
Stel dat je een nieuwe dictionary wilt maken op basis van een gegeven dictionary, maar dan met items die groter zijn dan 2. Dat betekent dat je een voorwaarde moet toevoegen aan het oorspronkelijke sjabloon dat je hierboven zag...
dict1 = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
# Check for items greater than 2
dict1_cond = {k:v for (k,v) in dict1.items() if v>2}
print(dict1_cond)
{'e': 5, 'c': 3, 'd': 4}
Dit valt mee! Maar wat als je meerdere voorwaarden hebt?
Meerdere if-voorwaarden
In het bovenstaande probleem: wat als je niet alleen de items groter dan 2 wilt, maar ook wilt controleren of ze tegelijk een veelvoud van 2 zijn?
dict1_doubleCond = {k:v for (k,v) in dict1.items() if v>2 if v%2 == 0}
print(dict1_doubleCond)
{'d': 4}
De oplossing voor het toevoegen van meerdere voorwaarden is simpelweg de voorwaarden achter elkaar in je comprehension plaatsen. Let er wel op wat je precies probeert te doen. Onthoud dat opeenvolgende if-statements werken alsof er and-clausules tussen staan.
Laten we nog een voorbeeld met drie voorwaarden bekijken:
dict1 = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f':6}
dict1_tripleCond = {k:v for (k,v) in dict1.items() if v>2 if v%2 == 0 if v%3 == 0}
print(dict1_tripleCond)
{'f': 6}
In een for-loop komt dit overeen met:
dict1_tripleCond = {}
for (k,v) in dict1.items():
if (v>=2 and v%2 == 0 and v%3 == 0):
dict1_tripleCond[k] = v
print(dict1_tripleCond)
{'f': 6}
If-else-voorwaarden
Werken met een if-else-voorwaarde is ook eenvoudig met dictionary comprehension. Bekijk het volgende voorbeeld:
dict1 = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f':6}
# Identify odd and even entries
dict1_tripleCond = {k:('even' if v%2==0 else 'odd') for (k,v) in dict1.items()}
print(dict1_tripleCond)
{'f': 'even', 'c': 'odd', 'b': 'even', 'd': 'even', 'e': 'odd', 'a': 'odd'}
Geneste dictionary comprehension
Nesten is een programmeerconcept waarbij data in lagen wordt georganiseerd of waar objecten andere soortgelijke objecten bevatten. Je hebt vast weleens een geneste if-structuur gezien: een if-voorwaarde binnen een andere if-voorwaarde.
Op dezelfde manier kunnen dictionary’s genest zijn en kunnen hun comprehensions dus ook genest zijn. Laten we zien wat dat betekent:
nested_dict = {'first':{'a':1}, 'second':{'b':2}}
float_dict = {outer_k: {float(inner_v) for (inner_k, inner_v) in outer_v.items()} for (outer_k, outer_v) in nested_dict.items()}
print(float_dict)
{'first': {1.0}, 'second': {2.0}}
Dit is een voorbeeld van een geneste dictionary. De nested_dict is een dictionary met de sleutels first en second, die in hun waarden dictionary-objecten bevatten. De code werkt met de binnenste dictionary-waarden, zet ze om naar float en combineert vervolgens de buitenste sleutels met de nieuwe float-waarden tot een nieuwe dictionary.
De code bevat ook een geneste dictionary comprehension, oftewel een dictionary comprehension binnen een andere. Genest kan zo’n comprehension lastig leesbaar en begrijpelijk worden, wat het hele doel van comprehensions ondergraaft.
Naarmate de structuur van de dictionary waarmee je werkt complexer wordt, wordt de dictionary comprehension dat ook. In zulke situaties kun je beter geen ingewikkelde comprehensions gebruiken.
Let op dat je de bovenstaande code ook kunt herschrijven met een geneste for-loop:
nested_dict = {'first':{'a':1}, 'second':{'b':2}}
for (outer_k, outer_v) in nested_dict.items():
for (inner_k, inner_v) in outer_v.items():
outer_v.update({inner_k: float(inner_v)})
nested_dict.update({outer_k:outer_v})
print(nested_dict)
{'first': {'a': 1.0}, 'second': {'b': 2.0}}
Tot slot
Hopelijk heb je nu geleerd over dictionary’s in Python, het concept van comprehension, en waarom en waar Python dictionary comprehension nuttig kan zijn.
Oefening baart kunst! Bekijk enkele van onze beste Python-tips en -trucs om je code te verbeteren, of volg onze track Python Data Fundamentals om de belangrijkste onderwerpen te beheersen.
Veelgestelde vragen over Python Dictionary Comprehension
Wat is dictionary comprehension in Python?
Dictionary comprehension is een beknopte en leesbare manier om dictionaries te maken in Python. Het biedt een manier om een nieuwe dictionary te maken op basis van een iterabel object zoals een lijst, tuple of set.
Wat is de syntax voor dictionary comprehension in Python?
De syntax voor dictionary comprehension in Python is als volgt: {key:value for (key,value) in iterable}
Hoe maak ik een dictionary van een lijst met dictionary comprehension in Python?
Je kunt een dictionary maken uit een lijst met dictionary comprehension in Python door over de lijst te itereren en de listelementen als sleutels en waarden in de nieuwe dictionary te gebruiken.
Kan ik voorwaarden gebruiken in dictionary comprehension in Python?
Ja, je kunt voorwaardelijke statements gebruiken in dictionary comprehension in Python om bepaalde elementen weg te filteren.
Wat zijn de voordelen van dictionary comprehension in Python?
De voordelen van dictionary comprehension in Python zijn dat het beknopt en leesbaar is en de hoeveelheid code vermindert die nodig is om dictionaries te maken. Het maakt ook filtering en transformatie van dictionary-elementen in één regel code mogelijk.
Ik heb in verschillende sectoren gewerkt en meerdere petten gedragen: softwareontwikkelaar, machine learning-onderzoeker, data scientist, productmanager. Maar in de kern ben ik een programmeur die graag leert en kennis deelt!

