Dictionaries
A dictionary is a map of keys to values. For example, this dictionary maps a key that is a meal to a value that is a string describing that meal:
meals = {
'breakfast': 'yogurt, granola, and fruit',
'lunch': 'Cupbop',
'dinner': 'lasagna and salad'
}
The purpose of the dictionary is to be able to store and look up key/value pairs. The dictionary above lets us store what we ate today and then to perform calculations on it.
This is similar to what meal tracking or fitness tracking apps do! The screenshot below shows how a meal tracking app stores a list of items along with their nutrition information for each meal. We will eventually show you how to store more complex information in a dictionary.
Basic operations
Here are a few of the basic things you can do with a dictionary
Create an empty dictionary
You can create a dictionary using the curly brackets notation shown above. This is an empty dictionary:
meals = {}
Add key/value pairs to a dictionary
You can add key/value pairs to the dictionary one at a time using square brackets:
meals['second lunch'] = 'crackers and cheese'
Dictionaries cannot have duplicate keys
This will over-write the value of the ‘lunch’ key:
meals['lunch'] = 'peanut butter and jelly sandwich'
The dictionary will now hold these key/value pairs:
{
'breakfast': 'yogurt, granola, and fruit',
'lunch': 'Cupbop',
'dinner': 'lasagna and salad',
}
Get key/value pairs from a dictionary
You can retrieve the value for a key also using square brackets:
print(meals['dinner'])
If you try to retrieve a key that is not present, you will get an error. For
example, asking for meals['brunch']
with the above example cause an error:
KeyError: 'brunch'
You can also use the get()
function:
result = meals.get('brunch', 'buttered toast and apple juice')
This tells Python to look for brunch
in the meals
dictionary and return the
value. But if that key doesn’t exist, then return
buttered toast and apple juice
instead.
Iterate over the key/value pairs in a dictionary
You can iterate over all of the keys and values using for ... in
and
items()
:
for meal, description in meals.items():
print(f'For {meal} we are serving {description}. 😋')
This will print:
For breakfast we are serving yogurt, granola, and fruit. 😋
For lunch we are serving Cupbop. 😋
For dinner we are serving lasagna and sald. 😋
When you call items()
you get an object that has a list of key/value tuples.
You can turn this into a list:
print(list(meals.items()))
This will print:
[('breakfast', 'yogurt, granola, and fruit'), ('lunch', 'Cupbop'), ('dinner', 'lasagna and sald')]
Types of keys
You can use numbers as the keys for a dictionary. For example, this dictionary maps a number to a description of whether that number has any useful properties:
significance = {
7: 'prime',
2: 'even prime',
3: 'prime',
5: 'prime',
9: 'square',
4: 'even square',
1: 'multiplicative identity'
}
Then we can print an entry using:
print(significance[5])
Checking whether a key is in a dictionary
You can check whether a key is in a dictionary using in
. For example:
print('dinner' in meals)
print('brunch' in meals)
will print
True
False
Likewise, using our significance
dictionary above:
for number in range(10):
if number in significance:
print(f'{number} is {significance[number]}.')
else:
print(f"I don't know anything special about {number}.")
This will print:
I don't know anything special about 0.
1 is multiplicative identity.
2 is even prime.
3 is prime.
4 is even square.
5 is prime.
I don't know anything special about 6.
7 is prime.
I don't know anything special about 8.
9 is even square.
Example: replacing words with emojis
The world can always use more emojis! You are given a dictionary mapping words to emojis. For example:
emojis = {'dog': '🐶', 'cat': '🐱', 'tree': '🌳', 'bird': '🐦'}
Your goal is to replace all instances of a word in a string with it’s corresponding emoji. You need to ignore the case of the word.
Using the dictionary above, the string 'My dog has fleas'
becomes
'My 🐶 has fleas'
.
Write a function to do this, add_emojis(text, emojis)
, and the function should
return a new string.
Here is a function to do this:
def add_emojis(text, emojis):
new_words = []
# split the text into words
for word in text.split():
# check if this word is in the dictionary as a key
if word in emojis:
# get the emoji from the dictionary that corresponds to this word
word = emojis[word]
# append either the original word or the emoji to the list of words
new_words.append(word)
# combine the new words into a string, with spaces between them, and return that string
return " ".join(new_words)
- We use
split()
to split the string into a set of words - We use
if word in emojis
to check if the dictionary has a key for a given word - We use
emojis[word]
to get the emoji for a given word - We use
join()
to turn a list of words back into a string, with each word separated by spaces
If we run this code:
emojis = {
'dog': '🐶',
'cat': '🐱',
'tree': '🌳',
'bird': '🐦'
}
result = add_emojis("The dog chased the cat which chased the bird that sat in the tree in my yard.", emojis)
print(result)
We get:
The 🐶 chased the 🐱 which chased the 🐦 that sat in the 🌳 in my yard.
Example: team assignments
Let’s imagine you want to write a small program to help community members register for sports teams at the local recreation center. You have a dictionary that maps age groups to team names:
teams_by_age = {
0: 'Team Toddlers',
3: 'Tiny Troupers',
6: 'Starting Stars',
9: 'Mighty Middles',
12: 'Too Cool',
15: 'Boundless'
}
You also have a list of participants and their ages:
participants = [
('Joe', 14),
('Jane', 6),
('Johnny', 4),
('Jennifer', 20),
('Jack', 16),
('Janice', 2)
]
You want to assign each participant to a team based on their age:
def assign_teams(participants, teams_by_age):
"""Returns a list of tuples of name and team."""
This function should return a list of tuples that list person name and team such as (‘Joe’,‘Too Cool’).
To figure out which team a person is assigned to, find the nearest multiple of 3 that is less than or equal to the participant age. You can do this with:
nearest_multiple = (age // 3) * 3
If the participant does not have an age-group assignment, their team is “Adult League”.
Here is code to do this:
def assign_teams(participants, teams_by_age):
# make a list of tuples (person, team)
result = []
# loop through all the tuples of (name, age)
for name, age in participants:
# compute the group for this age (nearest multiple of 3)
age_group = (age // 3) * 3
# loop up the team name for this age group, and if none, then the team is 'Adult League'
team_name = teams_by_age.get(age_group, "Adult League")
# append a tuple of (name, group) to the list of tuples
result.append((name, team_name))
return result
If we start with the two dictionaries above and then:
print(assign_teams(participants, teams_by_age))
we get:
[('Joe', 'Too Cool'), ('Jane', 'Starting Stars'), ('Johnny', 'Tiny Troupers'), ('Jennifer', 'Adult League'), ('Jack', 'Boundless'), ('Janice', 'Team Toddlers')]
Example — cipher
You are given a codex
, which is a dictionary mapping letters to their
“encoded” letter. Your job is to use this codex to encode a message.
For example, if the codex maps d -> x
, o -> p
, and g -> e
, then dog
is
encoded as xpe
. This is the most simple way of encoding messages and is really
easy for a computer to break, but it is usually the starting point to discuss
the concept of encryption.
The codex only contains lowercase letters, but you should encode uppercase letters also. Be sure to preserve casing.
Here is an example of a codex:
codex = {
'a': 'd',
'b': 'e',
'c': 'z',
'd': 'h',
'e': 'g',
'f': 's',
'g': 'n',
'h': 'r',
'i': 'a',
'j': 'b',
'k': 'k',
'l': 'j',
'm': 'c',
'n': 'u',
'o': 'y',
'p': 't',
'q': 'q',
'r': 'x',
's': 'w',
't': 'v',
'u': 'p',
'v': 'f',
'w': 'i',
'x': 'l',
'y': 'm',
'z': 'o'
}
Here is the function to write:
def encode(codex, message):
"""Return the encoded message using the codex to map letters."""
This works the same way as the emoji problem above! We just have to be sure to worry about case. Here is one way to solve this problem:
def encode(codex, message):
# accumulate a new string
result = ""
# loop through all of the characters in the message
for char in message:
# start out with the new character being the same as the old one
new_char = char
# check if the lowercase version of the character is in the codex
if char.lower() in codex:
# get the encoded character from the codex
new_char = codex[char.lower()]
if char.isupper():
# if the character was originally uppercase, be sure the new character is also uppercase
new_char = new_char.upper()
# note, any punctuation is left alone because it won't be in the codex!
# append the encoded character in the string
result += new_char
return result
If we use the codex above and then run:
print(encode(codex, 'I like fish.'))
we get:
A jakg sawr.