Dictionaries

What is a Dictionary?

A dictionary is an unordered set of key: value pairs.

Suppose we want to store the prices of various items sold at a cafe:

  • Oatmeal is 3 dollars
  • Avocado Toast is 6 dollars
  • Carrot Juice is 5 dollars
  • Blueberry Muffin is 2 dollars

In Python, we can create a dictionary called menu to store this data:

menu = {“oatmeal”: 3, “avocado toast”: 6, “carrot juice”: 5, “blueberry muffin”: 2}

 

Notice that:

  1. A dictionary begins and ends with curly braces ({ and }).
  2. Each item consists of a key (i.e., “oatmeal”) and a value (i.e., 3)
  3. Each key: value pair (i.e., “oatmeal”: 3 or “avocado toast”: 6) is separated by a comma (,)
  4. It’s considered good practice to insert a space () after each comma, but your code will still run without the space.

Dictionaries provide us with a way to map pieces of data to each other, so that we can quickly find values that are associated with one another.

Make a Dictionary

In the previous exercise we saw a dictionary that maps strings to numbers (i.e., “oatmeal”: 3). However, the keys can be numbers as well. For example, if we were mapping restaurant bill subtotals to the bill total after tip, a dictionary could look like:

subtotal_to_total = {20: 24, 10: 12, 5: 6, 15: 18}

 

Values can be any type. You can use a string, a number, a list, or even another dictionary as the value associated with a key!

For example:

students_in_classes = {“software design”: [“Aaron”, “Delila”, “Samson”], “cartography”: [“Christopher”, “Juan”, “Marco”], “philosophy”: [“Frederica”, “Manuel”]}

 

The list [“Aaron”, “Delila”, “Samson”], which is the value for the key “software design”, represents the students in that class.

You can also mix and match key and value types. For example:

person = {“name”: “Shuri”, “age”: 18, “siblings”: [“T’Chaka”, “Ramonda”]}

 

Invalid Keys

We can have a list or a dictionary as a value of an item in a dictionary, but we cannot use these data types as keys of the dictionary. If we try to, we will get a TypeError. For example:

powers = {[1, 2, 4, 8, 16]: 2, [1, 3, 9, 27, 81]: 3}

 

will yield:

TypeError: unhashable type: ‘list’

 

The word “unhashable” in this context means that this ‘list’ is an object that can be changed. Dictionaries in Python rely on each key having a hash value, a specific identifier for the key. If the key can change, that hash value would not be reliable. So the keys must always be unchangeable, hashable data types, like numbers or strings.

 

Empty Dictionary

A dictionary doesn’t have to contain anything. You can create an empty dictionary:

empty_dict = {}

 

We can create an empty dictionary when we plan to fill it later based on some other input. We will explore ways to fill a dictionary in the next exercise.

Add A Key

To add a single key : value pair to a dictionary, we can use the syntax:

my_dict[“new_key”] = “new_value”

 

For example, if we had our menu object from the first exercise:

menu = {“oatmeal”: 3, “avocado toast”: 6, “carrot juice”: 5, “blueberry muffin”: 2}

 

and we wanted to add a new item, “cheesecake” for 8 dollars, we could use:

menu[“cheesecake”] = 8

 

Now, menu looks like:

{“oatmeal”: 3, “avocado toast”: 6, “carrot juice”: 5, “blueberry muffin”: 2, “cheesecake”: 8}

Add Multiple Keys

If we wanted to add multiple key : value pairs to a dictionary at once, we can use the .update() method.

Looking at our sensors object from the first exercise:

sensors =  {“living room”: 21, “kitchen”: 23, “bedroom”: 20}

 

If we wanted to add 3 new rooms, we could use:

sensors.update({“pantry”: 22, “guest room”: 25, “patio”: 34})

 

which would add all three items to the sensors dictionary. Now, sensors looks like:

{“living room”: 21, “kitchen”: 23, “bedroom”: 20, “pantry”: 22, “guest room”: 25, “patio”: 34}

Overwrite Values

We know that we can add a key by using syntax like:

menu[‘avocado toast’] = 7

 

which will create a key ‘avocado toast’ and set the value to 7. But what if we already have an ‘avocado toast’ entry in the menu dictionary?

In that case, our value assignment would overwrite the existing value attached to the key ‘avocado toast’.

menu = {“oatmeal”: 3, “avocado toast”: 6, “carrot juice”: 5, “blueberry muffin”: 2}
menu[“oatmeal”] = 5
print(menu)

would yield:
{“oatmeal”: 5, “avocado toast”: 6, “carrot juice”: 5, “blueberry muffin”: 2}

 

Notice the value of “oatmeal” has now changed to 5.

List Comprehensions to Dictionaries

Let’s say we have two lists that we want to combine into a dictionary, like a list of students and a list of their heights, in inches:

names = [‘Jenny’, ‘Alexus’, ‘Sam’, ‘Grace’]
heights = [61, 70, 67, 64]

 

Python allows you to create a dictionary using a list comprehension, with this syntax:

students = {key:value for key, value in zip(names, heights)}
#students is now {‘Jenny’: 61, ‘Alexus’: 70, ‘Sam’: 67, ‘Grace’: 64}

 

Remember that zip() combines two lists into a list of pairs. This list comprehension:

  1. Takes a pair from the zipped list of pairs from names and heights
  2. Names the elements in the pair key (the one originally from the names list) and value (the one originally from the heights list)
  3. Creates a key : value item in the students dictionary
  4. Repeats steps 1-3 for the entire list of pairs

Using Dictionaries

Now that we know how to create a dictionary, we can start using already created dictionaries to solve problems.

In this lesson, you’ll learn how to:

  • Use a key to get a value from a dictionary
  • Check for existence of keys
  • Find the length of a dictionary
  • Iterate through keys and values in dictionaries

Get A Key

Once you have a dictionary, you can access the values in it by providing the key. For example, let’s imagine we have a dictionary that maps buildings to their heights, in meters:

building_heights = {“Burj Khalifa”: 828, “Shanghai Tower”: 632, “Abraj Al Bait”: 601, “Ping An”: 599, “Lotte World Tower”: 554.5, “One World Trade”: 541.3}

 

Then we can access the data in it like this:

>>> building_heights[“Burj Khalifa”]
828
>>> building_heights[“Ping An”]
599

Get an Invalid Key

Let’s say we have our dictionary of building heights from the last exercise:

building_heights = {“Burj Khalifa”: 828, “Shanghai Tower”: 632, “Abraj Al Bait”: 601, “Ping An”: 599, “Lotte World Tower”: 554.5, “One World Trade”: 541.3}

 

What if we wanted to know the height of the Landmark 81 in Ho Chi Minh City? We could try:

print(building_heights[“Landmark 81”])

 

But “Landmark 81” does not exist as a key in the building_heights dictionary! So this will throw a KeyError:

KeyError: ‘Landmark 81’

 

One way to avoid this error is to first check if the key exists in the dictionary:

key_to_check = “Landmark 81”

if key_to_check in building_heights:
  print(building_heights[“Landmark 81”])

 

This will not throw an error, because key_to_check in building_heights will return False, and so we never try to access the key.

Try/Except to Get a Key

We saw that we can avoid KeyErrors by checking if a key is in a dictionary first. Another method we could use is a try/except:

key_to_check = “Landmark 81”
try:
  print(building_heights[key_to_check])
except KeyError:
  print(“That key doesn’t exist!”)

 

When we try to access a key that doesn’t exist, the program will go into the except block and print “That key doesn’t exist!”.

Safely Get a Key

We saw in the last exercise that we had to add a key:value pair to a dictionary in order to avoid a KeyError. This solution is not sustainable. We can’t predict every key a user may call and add all of those placeholder values to our dictionary!

Dictionaries have a .get() method to search for a value instead of the my_dict[key]notation we have been using. If the key you are trying to .get() does not exist, it will return None by default:

building_heights = {“Burj Khalifa”: 828, “Shanghai Tower”: 632, “Abraj Al Bait”: 601, “Ping An”: 599, “Lotte World Tower”: 554.5, “One World Trade”: 541.3}

#this line will return 632:
building_heights.get(“Shanghai Tower”)

#this line will return None:
building_heights.get(“My House”)

 

You can also specify a value to return if the key doesn’t exist. For example, we might want to return a building height of 0 if our desired building is not in the dictionary:

>>> building_heights.get(‘Shanghai Tower’, 0)
632
>>> building_heights.get(‘Mt Olympus’, 0)
0
>>> building_heights.get(‘Kilimanjaro’, ‘No Value’)
‘No Value’

Delete a Key

Sometimes we want to get a key and remove it from the dictionary. Imagine we were running a raffle, and we have this dictionary mapping ticket numbers to prizes:

raffle = {223842: “Teddy Bear”, 872921: “Concert Tickets”, 320291: “Gift Basket”, 412123: “Necklace”, 298787: “Pasta Maker”}

 

When we get a ticket number, we want to return the prize and also remove that pair from the dictionary, since the prize has been given away. We can use .pop() to do this. Just like with .get(), we can provide a default value to return if the key does not exist in the dictionary:

>>> raffle.pop(320291, “No Prize”)
“Gift Basket”
>>> raffle
{223842: “Teddy Bear”, 872921: “Concert Tickets”, 412123: “Necklace”, 298787: “Pasta Maker”}
>>> raffle.pop(100000, “No Prize”)
“No Prize”
>>> raffle
{223842: “Teddy Bear”, 872921: “Concert Tickets”, 412123: “Necklace”, 298787: “Pasta Maker”}
>>> raffle.pop(872921, “No Prize”)
“Concert Tickets”
>>> raffle
{223842: “Teddy Bear”, 412123: “Necklace”, 298787: “Pasta Maker”}

 

.pop() works to delete items from a dictionary, when you know the key value.

Get All Keys

Sometimes we want to operate on all of the keys in a dictionary. For example, if we have a dictionary of students in a math class and their grades:

test_scores = {“Grace”:[80, 72, 90], “Jeffrey”:[88, 68, 81], “Sylvia”:[80, 82, 84], “Pedro”:[98, 96, 95], “Martin”:[78, 80, 78], “Dina”:[64, 60, 75]}

 

We want to get a roster of the students in the class, without including their grades. We can do this with the built-in list() function:

>>> list(test_scores)
[“Grace”, “Jeffrey”, “Sylvia”, “Pedro”, “Martin”, “Dina”]

 

Dictionaries also have a .keys() method that returns a dict_keys object. A dict_keysobject is a view object, which provides a look at the current state of the dictionary, without the user being able to modify anything. The dict_keys object returned by .keys() is a set of the keys in the dictionary. You cannot add or remove elements from a dict_keysobject, but it can be used in the place of a list for iteration:

for student in test_scores.keys():
  print(student)

 

will yield:

“Grace”
“Jeffrey”
“Sylvia”
“Pedro”
“Martin”
“Dina”

Get All Values

Dictionaries have a .values() method that returns a dict_values object (just like a dict_keys object but for values!) with all of the values in the dictionary. It can be used in the place of a list for iteration:

test_scores = {“Grace”:[80, 72, 90], “Jeffrey”:[88, 68, 81], “Sylvia”:[80, 82, 84], “Pedro”:[98, 96, 95], “Martin”:[78, 80, 78], “Dina”:[64, 60, 75]}

for score_list in test_scores.values():
  print(score_list)

 

will yield:

[80, 72, 90]
[88, 68, 81]
[80, 82, 84]
[98, 96, 95]
[78, 80, 78]
[64, 60, 75]

 

There is no built-in function to get all of the values as a list, but if you really want to, you can use:

list(test_scores.values())

 

However, for most purposes, the dict_list object will act the way you want a list to act.

Get All Items

You can get both the keys and the values with the .items() method. Like .keys() and .values(), it returns a dict_list object. Each element of the dict_list returned by .items() is a tuple consisting of:

(key, value)

 

so to iterate through, you can use this syntax:

biggest_brands = {“Apple”: 184, “Google”: 141.7, “Microsoft”: 80, “Coca-Cola”: 69.7, “Amazon”: 64.8}

for company, value in biggest_brands.items():
  print(company + ” has a value of “ + str(value) + ” billion dollars. “)

 

which would yield this output:

Apple has a value of 184 billion dollars.
Google has a value of 141.7 billion dollars.
Microsoft has a value of 80 billion dollars.
Coca-Cola has a value of 69.7 billion dollars.
Amazon has a value of 64.8 billion dollars.

Review

In this lesson, you’ve learned how to go through dictionaries and access keys and values in different ways. Specifically you have seen how to:

  • Use a key to get a value from a dictionary
  • Check for existence of keys
  • Find the length of a dictionary
  • Remove a key: value pair from a dictionary
  • Iterate through keys and values in dictionaries