It’s an object that stores information in the same way that a dictionary stores words and their definitions. Here’s an example of an English dictionary created using a dictionary object in Python:
# Create a dictionary
my_dictionary = {
'Apple': 'A fruit that grows on trees',
'Ball': 'Another name for a spherical object',
'Cart': 'Platform with wheels pulled by an animal',
}
In the above snippet we have:
my_dictionary
{}
- which are the symbols used by Python to show the start and end of a dictionary object:
- which separate the keys and the values to create key-value pairs (or items) in your dictionaryThese are the necessary components for creating a dictionary.
Essentially, a dictionary is a comma-separated list of key-value pairs inside of curly brackets
You index a dictionary (look up a value) by using square brackets and the relevant key:
# Look up the definition of 'apple'
print(my_dictionary['Apple'])
## A fruit that grows on trees
You can add items into a dictionary by indexing it with a new key and assigning a value to it:
# Add a new word and definition to the dictionary
my_dictionary['Python'] = 'A type of snake'
print(my_dictionary['Python'])
## A type of snake
Remember, an item is a key plus a value
Overwriting a value works in a similar way: index the dictionary with an existing key and assign a new value to it. The old value will be replaced:
# Replace the definition of the word 'Python'
my_dictionary['Python'] = 'A type of programming language'
print(my_dictionary['Python'])
## A type of programming language
The fact that the above code overwrites the value implies that keys must be unique - you can’t have two Python
keys in the same dictionary.
To delete an item, use the del
statement:
# Remove the word 'Ball' and its definition
del my_dictionary['Ball']
print(my_dictionary)
## {'Apple': 'A fruit that grows on trees', 'Cart': 'Platform with wheels pulled by an animal', 'Python': 'A type of programming language'}
The keys in a dictionary can be strings, numbers or tuples (or a combination of these):
# A dictionary with strings as keys
animal_types = {'Lion': 'Mammal', 'Bear': 'Mammal', 'Crocodile': 'Reptile', 'Eagle': 'Bird', 'Pigeon': 'Bird'}
print(animal_types['Lion'])
## Mammal
# A dictionary with numbers as keys
arabic_to_roman = {1: 'I', 2: 'II', 3: 'III', 4: 'IV', 5: 'V', 6: 'VI'}
print(arabic_to_roman[2])
## II
# A dictionary with tuples as keys
days_in_month = {('Nov', 2021): 30, ('Dec', 2021): 31, ('Jan', 2022): 31, ('Feb', 2022): 28, ('Mar', 2022): 31}
print(days_in_month[('Mar', 2022)])
## 31
# A dictionary with a combination of strings, numbers and tuples as keys
dct = {'A': 'Alfa', 1: 'Bravo', (2, 'C'): 'Charlie'}
print(dct[(2, 'C')])
## Charlie
You can’t have lists as keys because they are mutable (they can be modified in-place) which confuses Python
Of course, a key can be stored in a variable:
# Assign a key to a variable
var = 'A'
# Index a dictionary with the variable
print(dct[var])
## Alfa
The values in a dictionary can be any data type:
dct = {
'String': 'Alpha',
'Number': 1,
'Null': None,
'Boolean': True,
'List': [1, 2, 3, 4, 'Five', 'Six'],
'Dictionary': {'A': 'Alfa', 'B': 'Bravo', 'C': 'Charlie'},
'Tuple': (0, 'A'),
}
This implies that the values can be treated like their data types; for example, if a value is a list then all the methods that work on lists will work on the indexed dictionary.
# Augment a string
dct['String'] = dct['String'] + 'bet'
# Add to a number
dct['Number'] = dct['Number'] + 9
# Test equality
dct['Boolean'] = dct['Boolean'] == 'Value'
# Append to a list
dct['List'].append(3)
# Add to a dictionary within a dictionary
dct['Dictionary']['D'] = 'Delta'
# Slice a tuple
dct['Tuple'] = dct['Tuple'][1:]
print(dct)
## {'String': 'Alphabet', 'Number': 10, 'Null': None, 'Boolean': False, 'List': [1, 2, 3, 4, 'Five', 'Six', 3], 'Dictionary': {'A': 'Alfa', 'B': 'Bravo', 'C': 'Charlie', 'D': 'Delta'}, 'Tuple': ('A',)}
This can get as complex as you want:
# Use list comprehension, list indexing and a variable as the key
key = 'List'
idx = 4
dct[key] = dct[key][:idx] + [x + 4 for x in dct[key][:idx]]
print(dct['List'])
## [1, 2, 3, 4, 5, 6, 7, 8]
The length of a dictionary is the number of items inside it:
dct = {'A': 'Alfa', 'B': 'Bravo', 'C': 'Charlie'}
print(len(dct))
## 3
The .keys()
method returns all the keys as a ‘dict_keys’ object:
print(dct.keys())
## dict_keys(['A', 'B', 'C'])
It is usually useful to convert this into a list:
print(list(dct.keys()))
## ['A', 'B', 'C']
Similarly, the .values()
method will return all the values:
all_values = dct.values()
all_values = list(all_values)
print(all_values)
## ['Alfa', 'Bravo', 'Charlie']
Lastly, the .items()
method will return all of the items:
all_values = dct.items()
all_values = list(all_values)
print(all_values)
## [('A', 'Alfa'), ('B', 'Bravo'), ('C', 'Charlie')]
Notice that the list()
function converted the dictionary items into a list of tuples. This means that all the key-value pairs can be iterated over, in order, using a ‘for’ loop:
for key, value in dct.items():
print(key, value)
## A Alfa
## B Bravo
## C Charlie
Of course, a dictionary can be empty! Create an empty dictionary by simply not putting anything inside the curly brackets:
dct = {}
An empty dictionary can be useful for when you need the object to be initialised for something that happens downstream. Maybe there’s a loop that populates a dictionary and thus requires one to exist before it starts:
dct = {}
for day in ['Mon', 'Tues', 'Wednes', 'Thurs', 'Fri', 'Satur', 'Sun']:
dct[day] = day + 'day'
print(dct)
## {'Mon': 'Monday', 'Tues': 'Tuesday', 'Wednes': 'Wednesday', 'Thurs': 'Thursday', 'Fri': 'Friday', 'Satur': 'Saturday', 'Sun': 'Sunday'}
Another way to create an empty dictionary is by using the dict()
function with no arguments:
dct = dict()
Python actually uses the name dict instead of ‘dictionary’ for the object type:
print(type(dct))
## <class 'dict'>
Note that an empty dictionary is not the same as a dictionary that contains an empty list or a null:
# Not an empty dictionary
dct['Value 1'] = []
dct['Value 2'] = None
If it contains an empty list or a null it still contains something!
What’s a “named value”? These are most easily explained by using an example: consider the pow()
function in Python which raises a number to a power:
# Raise a number to a power
x = pow(10, 2)
print(x)
## 100
This has calculated \(10^2 = 100\). The pow()
function raises a base to an exponent. As it happens, this function names its inputs - the first is given the name “base” and the second is called “exp” - which means you can specify the arguments by their names:
# Raise a base to an exponent
x = pow(base=10, exp=2)
print(x)
## 100
This is what is meant by “named values”, it literally refers to values which have names! Of course, dictionaries consist of key-value pairs which associate names to values, but they are not quite the same. Fortunately, there is a way to convert dictionaries to named values: the double-asterisk operator:
# Create a dictionary
dct = {'base': 10, 'exp': 2}
# Use the dictionary as the input arguments to the pow() function
x = pow(**dct)
print(x)
## 100
What’s happened here is that the two asterisks have converted the two key-value pairs in the dictionary into two named values called “base” (with a value of 10) and “exp” (with a value of 2) which have then been used as named arguments for the pow()
function.
Another use for named values is when you want to merge two dictionaries:
# Results of the men's 400m finals at the last two Olympic Games
rio2016 = {'Wayde van Niekerk': 1, 'Kirani James': 2, 'LaShawn Merritt': 3}
tokyo2020 = {'Steven Gardiner': 1, 'Anthony Zambrano': 2, 'Kirani James': 3}
# Merge the two dictionaries to get the athletes' most recent finishing positions
most_recent = {**rio2016, **tokyo2020}
print(most_recent)
## {'Wayde van Niekerk': 1, 'Kirani James': 3, 'LaShawn Merritt': 3, 'Steven Gardiner': 1, 'Anthony Zambrano': 2}
Notice that when there are duplicate keys the value from the second dictionary overwrites the first: Kirani James came 2nd in Rio and 3rd in Tokyo, so the merged dictionary only keeps his most recent result.
Alternatively, as of Python 3.9, the ‘bar’ notation can be used to merge one dictionary into another:
rio2016 = {'Wayde van Niekerk': 1, 'Kirani James': 2, 'LaShawn Merritt': 3}
tokyo2020 = {'Steven Gardiner': 1, 'Anthony Zambrano': 2, 'Kirani James': 3}
most_recent = rio2016 | tokyo2020
print(most_recent)
## {'Wayde van Niekerk': 1, 'Kirani James': 3, 'LaShawn Merritt': 3, 'Steven Gardiner': 1, 'Anthony Zambrano': 2}
Or, the .update()
method can be used to merge in-place:
results = {'Wayde van Niekerk': 1, 'Kirani James': 2, 'LaShawn Merritt': 3}
new_results = {'Steven Gardiner': 1, 'Anthony Zambrano': 2, 'Kirani James': 3}
results.update(new_results)
print(results)
## {'Wayde van Niekerk': 1, 'Kirani James': 3, 'LaShawn Merritt': 3, 'Steven Gardiner': 1, 'Anthony Zambrano': 2}
The tabulate
package allows you to render a dictionary as a nice table:
from tabulate import tabulate
print(tabulate(results.items(), headers=['Name', 'Ranking'], tablefmt='pipe'))
## | Name | Ranking |
## |:------------------|----------:|
## | Wayde van Niekerk | 1 |
## | Kirani James | 3 |
## | LaShawn Merritt | 3 |
## | Steven Gardiner | 1 |
## | Anthony Zambrano | 2 |
Install this package from the terminal with pip3 install tabulate
.
Lists and dictionaries are two different data types in Python. Let’s compare them:
my_dictionary = {0: 'Alfa', 1: 'Bravo', 2: 'Charlie', 3: 'Delta', 4: 'Echo'}
my_list = ['Alfa', 'Bravo', 'Charlie', 'Delta', 'Echo']
A dictionary is defined with curly brackets and contains key-value pairs whereas a list is defined with square brackets and contains only values. A list is indexed with numbers that correspond to the positions of the values whereas a dictionary is indexed with keys (which can be numbers too, or they can be strings or tuples) that correspond to the values:
print(my_dictionary[2])
## Charlie
print(my_list[2])
## Charlie
A dictionary is ordered just like a list is. This means that its items appear in the same order as they were created/added to the dictionary:
print(list(my_dictionary.values())[2])
## Charlie
The implication is that dictionaries have two properties that lists do not:
my_dictionary = {1: 'Alfa', 2: 'Bravo', 3: 'Charlie', 4: 'Delta', 5: 'Echo'}
print(my_dictionary[2])
## Bravo
Using the index “2” has returned the second item in the dictionary! You can, of course, not have the numerical indexes be sequential at all if you so wanted.
my_dictionary = {'A': 'Alfa', 'B': 'Bravo', 'C': 'Charlie', 'D': 'Delta', 'E': 'Echo'}
print(my_dictionary['B'])
## Bravo
print(list(my_dictionary.values())[1])
## Bravo
For the record, you can always convert a list into a dictionary by enumerating it (assigning a number to each value):
# Convert a list into a dictionary
dct = dict(enumerate(my_list))
print(dct)
## {0: 'Alfa', 1: 'Bravo', 2: 'Charlie', 3: 'Delta', 4: 'Echo'}
And, finally, just like you can have lists-of-lists and list comprehensions, you can have dictionaries-of-dictionaries and dictionary comprehensions! See this page for more on those…