To start this guide, download this zip file.
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.
Getting key/value pairs from a dictionary
You can retrieve the value for a key by using square brackets:
food = 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:
food = 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.
Here are these ideas put into a program, which is in meals.py
:
if __name__ == '__main__':
meals = {
'breakfast': 'yogurt, granola, and fruit',
'lunch': 'Cupbop',
'dinner': 'lasagna and salad'
}
food = meals['dinner']
print(f"I had {food} for dinner.")
food = meals.get('brunch', 'buttered toast and apple juice')
print(f"I had {food} for brunch.")
If you run this program, you get:
I had lasagna and salad for dinner.
I had buttered toast and apple juice for brunch.
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}. ๐')
The file all_meals.py
has this short program:
if __name__ == '__main__':
meals = {
'breakfast': 'yogurt, granola, and fruit',
'lunch': 'Cupbop',
'dinner': 'lasagna and salad'
}
for meal, description in meals.items():
print(f'For {meal} we are serving {description}. ๐')
If you run it, 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. ๐
To understand what items()
is doing, it uses your dictionary, gets all of the
key/value pairs, and returns a sequence 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')]
Checking whether a key is in a dictionary
You can check whether a key is in a dictionary using in
. For example:
if 'dinner' in meals:
print("Yay, we are eating dinner.")
if 'brunch' in meals:
print("Yay, we are eating brunch.")
will print
print("Yay, we are eating dinner.")
Here is another example, which is in home_towns.py
:
if __name__ == '__main__':
hometowns = {
'Dallin Oaks': 'Provo, UT',
'Jeffery Holland': 'St George, UT',
'Merril Bateman': 'Lehi, UT',
'Cecil Samuelson': 'Salt Lake City, UT',
'Kevin Worthen': 'Dragerton, UT',
'Shane Reese': 'Logan, UT'
}
for person in ['Kevin Worthen', 'Henry Eyring', 'Shane Reese', 'Ernest Wilkinson', 'Karl Maeser']:
if person in hometowns:
print(f'{person} was born in {hometowns[person]}.')
else:
print(f"I don't know where {person} was born.")
Here the dictionary maps Presidents of BYU to the place they were born. If you run this code you will see:
Kevin Worthen was born in Dragerton, UT.
I don't know where Henry Eyring was born.
Shane Reese was born in Logan, UT.
I don't know where Ernest Wilkinson was born.
I don't know where Karl Maeser was born.
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)
. We have given you
starter code in emojis.py
:
import sys
def add_emojis(text: str, emojis: dict[str, str]) -> str:
"""Replace words in `emojis` with their corresponding symbols."""
# Write code here
pass
if __name__ == '__main__':
emojis = {
'dog': '๐ถ',
'puppy': '๐ถ',
'dogs': '๐ถ๐ถ',
'cat': '๐ฑ',
'tree': '๐ณ',
'bird': '๐ฆ'
}
print(add_emojis(sys.argv[1], emojis))
Here is a solution:
def add_emojis(text: str, emojis: dict[str, str]) -> str:
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 the code
python emojis.py "The dog chased the cat which chased the bird that sat in the tree in my yard."
We get:
The ๐ถ chased the ๐ฑ which chased the ๐ฆ that sat in the ๐ณ in my yard.
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: dict[str, int], teams_by_age: dict[str, int]) -> list[tuple[str, str]]:
"""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โ.
There is starter code in assign_teams.py
:
def assign_teams(participants: dict[str, int], teams_by_age: dict[str, int]) -> list[tuple[str, str]]:
"""Return a list of (person, team) tuples"""
# Write code here
pass
def print_teams(teams: list[tuple[str, str]]):
for player, team in teams:
print(f'{player} is on team {team}')
def main(participants, age_groups):
teams = assign_teams(participants, age_groups)
print_teams(teams)
if __name__ == '__main__':
age_groups = {
0: 'Team Toddlers',
3: 'Tiny Troupers',
6: 'Starting Stars',
9: 'Mighty Middles',
12: 'Too Cool',
15: 'Boundless'
}
participants = [
('Joe', 14),
('Jane', 6),
('Johnny', 4),
('Jennifer', 20),
('Jack', 16),
('Janice', 2)
]
main(participants, age_groups)
Here is code to do this:
def assign_teams(participants: dict[str, int], teams_by_age: dict[str, int]) -> list[tuple[str, str]]:
# 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
- go through all the participants, which are tuples of (name, age)
- find the nearest age group for the participant
- get the team for that age group
- create a new tuple of (name, team) and append to a list of tuples
- return all the tuples
If we run the code, then we get:
[('Joe', 'Too Cool'), ('Jane', 'Starting Stars'), ('Johnny', 'Tiny Troupers'), ('Jennifer', 'Adult League'), ('Jack', 'Boundless'), ('Janice', 'Team Toddlers')]
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: dict[str, str], message: str) -> str:
"""Return the encoded message using the codex to map letters."""
You have some starter code in encode.py
:
import sys
def encode(codex: dict[str, str], message: str) -> str:
"""Return the encoded message using the codex to map letters."""
# Write code here
pass
def main(message, codex):
encoded = encode(codex, message)
print(encoded)
if __name__ == '__main__':
simple_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'
}
main(sys.argv[1], simple_codex)
This works the same way as the emoji problem above! You just have to be sure to worry about case.
Here is one way to solve this problem:
def encode(codex: dict[str, str], message: str) -> str:
# 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 run the completed code:
python encode.py "I like fish."
we get:
A jakg sawr.