Dictionaries

How do you store data in pairs?

KEY TERMS

  • Dictionary: a data structure that stores elements in key: value pairs

  • Key: a unique object that identifies a value in a dictionary

  • Value: an object that is stored in a dictionary

  • Curly brackets: { }, also called curly braces

  • Square brackets: [ ], lists lie between square brackets. These are used to access elements in lists and dictionaries

  • Mutable objects: objects whose fields can change. Lists are mutable objects; we can add to and delete elements from lists. Strings are immutable objects, so changing a string ("a" => "at") creates a new string and deletes the old one.

Dictionaries

Although lists are useful for storing multiple items, they can only store one aspect of these items. For instance, we can have a list of item names ["apples", "oranges", "bananas"], or item prices [1.3, 2.2, 1.0]. What if we wanted to store each item and its price? This is where dictionaries come in. Having the ability to relate those two lists makes them a lot more informative.

Like lists, dictionaries store multiple items, but they store each item in pairs. Each element in a dictionary includes two related values, such as an item with its price or a song with its artist.

Creating and Accessing a Dictionary

We can identify dictionaries by using curly braces/brackets in code. We can create an empty dictionary with curly brackets with nothing between them, similar to creating an empty list using square brackets. We can create a dictionary with elements by listing each item between the curly braces and formatting them into key: value pairs. Each pair has a colon between the key and value, and all individual pairs are separated by commas.

# here's an empty dictionary
>>> d = {}

# here's a dictionary used to store people's phone numbers
>>> phone_numbers = {'Sam': 3431234098, 'Daisy': 5672349876, 'John': 8907654321}

The value of a dictionary is determined by the key. You can think of a dictionary as a system which gives you the value when you ask for the key. In the example above, the keys are the names of people, and the values are the phone numbers of the person whose name is the key.

Keys

Values

'Sam'

----->

3431234098

'Daisy'

----->

5672349876

'John'

----->

8907654321

Let’s say you want to know what John's phone number is. We access items in dictionaries using the keys -- in this example, we can access someone's phone number using their name.

To access the value associated with the key ‘John’, we use square brackets containing the key.

# let’s find the value mapped to the key 'John'
>>> phone_numbers['John']
8907654321

Note that dictionaries use keys to reference values, unlike lists! Do you remember how we access items in lists? Answer: By the item's index or position.

Dictionaries are, as a result, unordered. In the phone numbers example, it doesn't matter what order the names are in because the phone numbers (the values) only depend on the names (the keys), not their position in the dictionary. We wouldn't care about getting the 2nd phone number, especially because we wouldn't know whose number that is!

Another feature of dictionaries is that the keys and values don’t have to have the same type! In our phone numbers dictionary above, note that the keys are all strings while the values are numbers. However, the following dictionary is also perfectly valid:

dict = {2018: 'data science', 'is cool': True, 0.0: {'another dictionary': 1.0}}

Of course, this dictionary doesn’t make much sense, but it shows that you can use many different types of objects in a dictionary. One important exception to keep in mind, however, is that you can’t use a list or a dictionary as a key. This is because lists and dictionaries are called mutable objects, which basically means they can be changed (mutable and immutable objects are outside the scope of this textbook, so you don't need to worry too much about this concept).

Why do you think having a mutable object (an object that can be modified) as a key in a dictionary might be a bad idea?

Adding, Modifying, and Removing Items

A dictionary can have values that repeat. For instance, let's say Daisy and John share a home phone. Our dictionary could store the same number for both the "Daisy" and "John" keys. However, keys must be unique, or we wouldn't be able to find values by using keys.

For example, let’s say we want to add the phone number of another person named Sam. If we were to access Sam's phone number, how would the dictionary know which phone number we are looking for?

In fact, if we were to add a new phone number under the name "Sam", this new phone number would replace the original number associated to Sam. This is how we add and change items to a dictionary. We use square brackets and an equals sign to assign a new key to a new value.

# our original dictionary
>>> phone_numbers = {'Sam': 3431234098, 'Daisy': 5672349876, 'John': 8907654321}

# we're reassigning the key 'Sam' to a different value
>>> phone_numbers['Sam'] = 1234567890

# let's add Nick's phone number
>>> phone_numbers['Nick'] = 4568905432

# phone numbers now looks like this. Spot the two changes.
>>> phone_numbers
{'Sam': 1234567890, 'Daisy': 5672349876, 'John': 8907654321, 'Nick': 4568905432}

How is assigning a new key: value pair in a dictionary different from accessing a value associated with a key in a dictionary?

Note that we didn't add two phone numbers for Sam. The code above didn't add a new key: value pair to the dictionary because we tried to add a key that the dictionary already contained. Dictionaries can only have unique keys, so it replaced Sam's phone number instead of adding another one!

A simple way to check if a dictionary already contains a key before adding a new key is to use the format <key> in <dictionary name> or <key> not in <dictionary name>. These statements return Boolean values that tell you whether or not a particular key is contained in a dictionary.

# this will return True because phone_numbers doesn't contain 'Mandy'
>>> 'Mandy' not in phone_numbers
True

# this will return True because phone_numbers does contain the key 'Daisy'
>>> 'Daisy' in phone_numbers
True

in and not in can only tell you about the keys in a dictionary, not the values!

We know that phone_number already contains the key 'Sam'. So, how can we add a phone number of another person named Sam into the dictionary without replacing or losing any of the old information? We could do something like this:

# the key 'Sam' seems to be too generic
# let's remove 'Sam' and replace it with a more specific key
# we can use del to remove keys from a dictionary
>>> del phone_numbers['Sam']
>>> phone_numbers
{'Daisy': 5672349876, 'John': 8907654321, 'Nick': 4568905432}

# now let’s put the original phone number back into the dictionary 
# this time we’ll be more specific and call it 'Sam O.'
>>> phone_numbers['Sam O.'] = 3431234098

# finally let’s add our second Sam's phone number with a different key:
>>> phone_numbers['Sam N.'] = 1234567890

# now the dictionary will have unique keys for both Sam's
>>> phone_numbers
{'Daisy': 5672349876, 'John': 8907654321, 'Nick': 4568905432, 'Sam O.': 3431234098, 'Sam N.': 1234567890}

There are other ways we could have added this information to the dictionary, but the code above demonstrates how combining a few simple commands and lines of code can make a big difference!

Here we've accomplished three things:

  1. First, we deleted the original key 'Sam' by using the format del <dictionary name>[<key>] and referencing the key that we wanted to remove from the dictionary. (This is similar to how we used del to remove items from a list!)

  2. Then, we added a new key: value pair to the dictionary ('Sam O.': 3431234098) using square brackets containing the key 'Sam O.' and an assignment statement. This was our original 'Sam', but we gave him a more specific key to distinguish between the original Sam and the new one.

  3. Finally, we added our new 'Sam N.' assigned to Sam N.'s phone number, 1234567890.

We can verify that we've successfully added a new key: value pair by checking the length of phone_numbers We can use the len() function, just like we did with lists, to check the length of a dictionary. This will return the number of key: value pairs in that dictionary.

# this will return 5 because we have 5 key: value pairs
>>> len(phone_numbers)
5

Dictionary Methods

Suppose we'd like to get a list of only the keys in a dictionary. There's a method for that! Using the dictionary method .keys() will return all of the keys contained in a dictionary. To format and view these keys as a list, we can call the function list() on the dictionary keys.

# here's a dictionary of students and their ages
>>> student_ages = {'Amy': 34, 'Lin': 25, 'Maria': 41, 'Peter': 32}
# we only want the names of the students in a list
>>> list(student_ages.keys())
['Amy', 'Lin', 'Maria', 'Peter']

Similarly, we can use the list() function and the .values() method to get a list of the values in a dictionary.

# now we only want the ages of the students in a list
>>> list(student_ages.values())
[34, 25, 41, 32]

Summary

  • Dictionaries are series of key-value pairs.

  • Create an empty dictionary: <dictionary name> = {}

  • Create a dictionary with items: <dictionary name> = {<key 1>: <value 1>, <key 2>: <value 2>, ...}

  • Access a value: <dictionary name>[<target key>]

  • Add an item: <dictionary name>[<new key>] = <key's value>

  • Change a value: <dictionary name>[<existing key>] = <key's new value>

  • Removing an item: del <dictionary name>[<target key>]

  • Check contents of dictionary: <key> (not) in <dictionary name>

Last updated