Building Dictionaries
Remeber: a dictionary is a map of keys to values:
So far we have shown you how to use dictionaries:
# a dictionary
meals = {
'breakfast': 'yogurt, granola, and fruit',
'lunch': 'Cupbop',
'dinner': 'lasagna and salad'
}
# get the value for a key
food = meals['dinner']
In this guide we will show you how to build a dictionary.
Building a dictionary
There are two steps to building a dictionary, (1) creating an empty dictionary, and (2) adding key/value pairs to the dictionary.
Creating an empty dictionary
You can create an empty dictionary using a pair of curly braces:
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['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'
Putting these together
If you want to create an entire dictionary from scratch:
meals = {}
meals['breakfast'] = 'ogurt, granola, and fruit'
meals['lunch'] = 'Cupbop'
meals['dinner'] = 'lasagna and salad'
You can do this in one step with:
meals = {
'breakfast': 'yogurt, granola, and fruit',
'lunch': 'Cupbop',
'dinner': 'lasagna and salad',
}
But there will be time when you will need to build a dictionary one item at a time. We will see examples of this below.
Room assignments
You are helping to organize the next Women in Computer Science (WICS) Skillathon, where students can come hear various speakers in CS provide brief workshops on various tech skills. You have a list of speakers and a list of available rooms. You want to pair up speakers with a room. Write a function that takes a list of speakers and a list of rooms (both having the same length) and returns a dictionary of room assignments.
Let’s say that you have these two lists:
speakers = ['Page', 'Jones', 'Bean', 'Zappala', 'Clement', 'Fulda']
rooms = ['2233', '2228', '2230', '2242', '2220', '2238']
You want to write a function make_room_assignments()
that creates a dictionary
mapping each speaker to a room:
def make_room_assignments(speakers, rooms):
"""
Return a dictionary mapping each speaker to a room
"""
To solve this problem, you need to iterate over two lists at a time, so that you
can map “Page” to “2233, “Jones to “2228”, and so forth. Remember, zip
helps
you iterate over two lists:
Zip creates a list of tuples. It makes these tuples by taking one element from each list at a time.
Here is how we can use this in a solution, which you can find in
room_assignments.py
:
def make_room_assignments(speakers: list[str], rooms: list[str]) -> dict[str, str]:
"""
Return a dictionary mapping each speaker to a room
"""
# create an empty dictionary
assignments = {}
# zip the speakers and rooms, then loop through all of the tuples
for speaker, room in zip(speakers, rooms):
# map the speaker to the room in the dictionary
assignments[speaker] = room
# return the dictionary
return assignments
if __name__ == '__main__':
speakers = ['Page', 'Jones', 'Bean', 'Zappala', 'Clement', 'Fulda']
rooms = ['2233', '2228', '2230', '2242', '2220', '2238']
room_assignments = make_room_assignments(speakers, rooms)
print(room_assignments)
Look through the comments in the code to see what each line is doing. Notice how we:
- create an empty dictionary
- zip the speaker and room lists together, then loop through the tuples
- add each speaker to room mapping to the dictionary
- return the dictionary at the end
If you run this program, you should see:
{'Page': '2233', 'Jones': '2228', 'Bean': '2230', 'Zappala': '2242', 'Clement': '2220', 'Fulda': '2238'}
Itineraries
This problem continues on from the previous one. Now that you have a list of speakers and room assignments, you need to assign each speaker to a time. You are given a list of speakers and their desired speaking times. You need to write a function that takes:
- desired_speaker_times: a list of (speaker, time) tuples
- room_assignments: a dictionary that maps speakers to rooms
and returns a list of speaker/room/time tuples.
def make_itinerary(desired_speaker_times: list[tuple[str, str]], room_assignments: dict[str, str]) -> list[tuple[str, str, str]]:
"""
desired_speaker_times: list of (speaker, time) tuples
room_assignments: a dictionary that maps speakers to rooms
Return a list of (speaker, room, time) tuples
"""
This picture illustrates what we are trying to do:
Notice that this function takes a list of (speaker, time) tuples and returns (speaker, room, time) tuples. So you can solve this problem by iterating through the desired speaker times and creating a new list of tuples as you go:
def make_itinerary(desired_speaker_times: list[tuple[str, str]], room_assignments: dict[str, str]):
"""
Input: list of (speaker, time) tuples
Return a list of (speaker, room, time) tuples
"""
# create an empty list
itinerary = []
# iterate through the list of (speaker, time) tuples
for speaker, time in desired_speaker_times:
# append a new tuple to the list, using the dictionary to look up the room for the speaker
itinerary.append((speaker, room_assignments[speaker], time))
return itinerary
if __name__ == '__main__':
desired_lineup = [('Fulda', '9am'), ('Page', '10am'), ('Jones', '11am'), ('Zappala', '12pm')]
room_assignments = {'Page': '2233', 'Jones': '2228', 'Bean': '2230', 'Zappala': '2242', 'Clement': '2220', 'Fulda': '2238'}
itinerary = make_itinerary(desired_lineup, room_assignments)
print(itinerary)
The key piece of this is where we create the new list of tuples:
itinerary.append((speaker, room_assignments[speaker], time))
Notice that we create a new tuple of (speaker, room, time), and we get the
middle piece of this — the room — by looking up the room in the
room_assignments
dictionary.
If you run the program, which is in itinerary.py
, you should see:
[('Fulda', '2238', '9am'), ('Page', '2233', '10am'), ('Jones', '2228', '11am'), ('Zappala', '2242', '12pm')]
Inverting a dictionary
The speaker-to-room dictionary was helpful for making individual itineraries. Now the building scheduling crew wants a dictionary that maps rooms to speakers. Because the room-assignments dictionary is 1-to-1 (the keys and the values are all unique), we can do this.
You should write a function called invert_assignments
that takes the room
assignments dictionary:
- room_assignments: a dictionary that maps speakers to rooms
and returns a new dictionary that maps rooms to speakers.
This picture illustrates what we are trying to do:
To do this, you need to iterate through all of the (speaker, room) tuples in the
room_assignments
dictionary, which you can do using items()
:
def invert_assignments(speaker_rooms: dict[str, str]) -> dict[str, str]:
"""
Return a new dictionary mapping room to speaker
"""
# create an empty dictionary
room_speakers = {}
# loop through all of the (speaker, room) tuples in the dictionary
for speaker, room in speaker_rooms.items():
# create a new entry in the new dictionary, mapping room to speaker
room_speakers[room] = speaker
# return the new dictionary
return room_speakers
if __name__ == '__main__':
room_assignments = {'Page': '2233', 'Jones': '2228', 'Bean': '2230', 'Zappala': '2242', 'Clement': '2220', 'Fulda': '2238'}
assigned_rooms = invert_assignments(room_assignments)
print(assigned_rooms)
Notice that we are making room to speaker, when the original dictionary mapped speaker to room:
room_speakers[room] = speaker
When you run this code, it should show:
{'2233': 'Page', '2228': 'Jones', '2230': 'Bean', '2242': 'Zappala', '2220': 'Clement', '2238': 'Fulda'}
Everything all at once
We can put all of these pieces into one program that:
- makes room assignments
- makes an itinerary
- makes the assigned rooms
You can see this program in skillathon.py
:
def make_room_assignments(speakers: list[str], rooms: list[str]):
"""
Return a dictionary mapping each speaker to a room
"""
assignments = {}
for speaker, room in zip(speakers, rooms):
assignments[speaker] = room
return assignments
def make_itinerary(desired_speaker_times: list[tuple[str, str]], room_assignments: dict[str, str]) -> list[tuple[str, str, str]]:
"""
Input: list of (speaker, time) tuples
Return a list of (speaker, room, time) tuples
"""
# create an empty list
itinerary = []
# iterate through the list of (speaker, time) tuples
for speaker, time in desired_speaker_times:
# append a new tuple to the list, using the dictionary to look up the room for the speaker
itinerary.append((speaker, room_assignments[speaker], time))
return itinerary
def invert_assignments(speaker_rooms: dict[str, str]) -> dict[str, str]:
"""
Return a new dictionary mapping room to speaker
"""
# create an empty dictionary
room_speakers = {}
# loop through all of the (speaker, room) tuples in the dictionary
for speaker, room in speaker_rooms.items():
# create a new entry in the new dictionary, mapping room to speaker
room_speakers[room] = speaker
# return the new dictionary
return room_speakers
def print_room_assignments(assignments: dict[str, str]):
print("Room Assignments:")
for speaker, room in assignments.items():
print(f"* {speaker}: {room}")
def print_itinerary(itinerary: list[tuple[str, str, str]]):
print("The itinerary:")
for speaker, room, time in itinerary:
print(f"* {speaker}: {room}, {time}")
def print_assigned_rooms(assigned_rooms: dict[str, str]):
print("Assigned rooms:")
for room, speaker in assigned_rooms.items():
print(f"* {room}: {speaker}")
if __name__ == '__main__':
# Make the room assignments and print them out
speakers = ['Page', 'Jones', 'Bean', 'Zappala', 'Clement', 'Fulda']
rooms = ['2233', '2228', '2230', '2242', '2220', '2238']
room_assignments = make_room_assignments(speakers, rooms)
print_room_assignments(room_assignments)
print()
# Make an itinerary and print it out
desired_lineup = [('Fulda', '9am'), ('Page', '10am'), ('Jones', '11am'), ('Zappala', '12pm')]
the_itinerary = make_itinerary(desired_lineup, room_assignments)
print_itinerary(the_itinerary)
print()
# Make a list of assigned rooms and print it out
rooms = invert_assignments(room_assignments)
print_assigned_rooms(rooms)
We have also added some nicer printing by iterating through the dictionaries and lists and printing them out with bullets. If you run this program, you get:
Room Assignments:
* Page: 2233
* Jones: 2228
* Bean: 2230
* Zappala: 2242
* Clement: 2220
* Fulda: 2238
The itinerary:
* Fulda: 2238, 9am
* Page: 2233, 10am
* Jones: 2228, 11am
* Zappala: 2242, 12pm
Assigned rooms:
* 2233: Page
* 2228: Jones
* 2230: Bean
* 2242: Zappala
* 2220: Clement
* 2238: Fulda