Dictionaries
Contents
Dictionaries#
Goals of this lecture#
The goal of this lecture is to introduce dictionaries. Python dictionaries are incredibly powerful objects, which you’ll end up using a lot (as well as variants of dictionaries) in your work.
- What is a dictionary? How is it different from a - list?
- How do you create a dictionary? 
- How do you index into a dictionary? 
- Updating a dictionary. 
- Iterating through a dictionary. 
What is a dictionary?#
In Python, a dictionary, or
dict, is a mutable collection of items, which stores key/value pairings.
Key features:
- Mutable: dictionaries can be updated. 
- Collection: like a - list, dictionaries can contain multiple entries.
- Key/value pairings: unlike a - list, dictionary entries consist of a key (i.e., how you index into that entry), and its value (i.e., what it maps onto).
Simple example of a dict#
A dictionary is very useful for storing structured information.
person = {'Name': 'Sean Trott',
          'Occupation': 'Assistant Teaching Professor',
          'Location': 'San Diego'}
print(type(person))
print(person)
<class 'dict'>
{'Name': 'Sean Trott', 'Occupation': 'Assistant Teaching Professor', 'Location': 'San Diego'}
They also make it really easy to access that information.
print(person['Name'])
print(person['Occupation'])
Sean Trott
Assistant Teaching Professor
dict vs. list#
We could store the same information in a list, but it would be a little harder to work with.
person_list = ['Sean Trott', 
               'Assistant Teaching Professor', 
               'San Diego']
To access the information, we have to remember where a particular value was stored. This is harder to do, especially if there’s not any intrinsic ordering to the values.
print(person_list[0])
Sean Trott
Rules about keys and values#
- A - dictcannot contain duplicate keys. That is, all keys must be unique.
- However, multiple keys can have the same value. 
## Different keys, same value
fruits = {'apple': 25, 
         'banana': 25}
fruits
{'apple': 25, 'banana': 25}
How do you create a dictionary?#
A dictionary (dict) can be created with curly brackets {}, along with the syntax {key_name:value}.
simple_dict = {'a': 1,
              'b': 2}
simple_dict
{'a': 1, 'b': 2}
simple_dict['a']
1
Keys vs. values#
Keys are your access-point into a dictionary.
- Must be an immutable type (e.g., a - stror- int); they can’t be a- list.
- Not all keys must be of same - type.
Values are what the keys map onto.
- Values can be anything: a - str,- int,- list, or even another- dict.
allowable_dict = {'a': [1, 2, 3]}
allowable_dict['a']
[1, 2, 3]
bad_key = {[1, 2, 3]: 'a'}
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [9], in <cell line: 1>()
----> 1 bad_key = {[1, 2, 3]: 'a'}
TypeError: unhashable type: 'list'
Dictionary length#
The len of a dict is the number of keys that it has (not the number of values).
allowable_dict = {'a': [1, 2, 3],
                 'b': [2, 3, 4, 5, 6, 8]}
len(allowable_dict)
Check-in#
What would the len of the dictionary below?
test_dict = {'Artist': 'The Beatles',
            'Songs': ['Hey Jude', 'Revolution', 
                      'In My Life']}
### Your code here
Check-in#
What would the len of the dictionary below?
test_dict = {'name': 'Sean',
            'items': {'food': 'sandwich',
                     'money': '$40'}}
### Your code here
Indexing into a dictionary#
Once you’ve created a dictionary, you’ll want to access the items in it.
- An advantage of a - dict(over a- list) is that key/value pairings are inherently structured.
- So rather than indexing by position, you can index by key. 
The syntax for indexing is: dict_name[key_name].
person = {'Name': 'Sean Trott',
          'Occupation': 'Assistant Teaching Professor',
          'Location': 'San Diego'}
print(person['Name'])
Sean Trott
print(person['Location'])
San Diego
Check-in#
How would you retrieve the value 25 from the dictionary below?
test_dict = {'apple': 25,
            'banana': 37}
### Your code here
Indexing requires a key#
To index into a dict, you need to use the key.
- The position of a value will not work. 
- The value itself will also not work. 
test_dict[0] ### will throw an error
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
Input In [17], in <cell line: 1>()
----> 1 test_dict[0]
KeyError: 0
test_dict[25] ### will throw an error
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
Input In [16], in <cell line: 1>()
----> 1 test_dict[25]
KeyError: 25
Updating a dict#
Once you’ve created a dict, it’s not set in stone––there are multiple ways to modify that dictionary.
- Adding new entries. 
- Deleting existing entries. 
- Combining two dictionaries. 
Adding new entries#
## First, let's create a new dictionary
registrar = {'Trott': 'COGS',
            'Fleischer': 'COGS'}
print(registrar)
{'Trott': 'COGS', 'Fleischer': 'COGS'}
We can add a new entry using the dict_name[key_name] = new_value syntax.
## Now we add a new entry to the dictionary
registrar['Styler'] = 'LING'
print(registrar)
{'Trott': 'COGS', 'Fleischer': 'COGS', 'Styler': 'LING'}
Check-in#
Add an entry for the price of "pasta" to prices_dict below using this new syntax.
prices_dict = {'rice': 4, 'bananas': 3}
### Your code here
Check-in#
What would the len of prices_dict be after you’ve added that entry?
### How long is prices_dict after you've added "pasta"?
Deleting entries#
We can also use the del function to delete specific key/value pairs from a dictionary.
## First, we create a new dictionary.
attendance = {'A1': True, 'A2': False}
print(attendance)
{'A1': True, 'A2': False}
## Then, we delete the entry with the "A2" key.
del(attendance['A2'])
print(attendance)
{'A1': True}
Merging dictionaries using update#
What if we have two different dictionaries that we want to combine or merge?
The update function can be used to do this.
## First, we create a new dictionary.
registrar = {'Trott': 'COGS',
            'Fleischer': 'COGS'}
print(registrar)
{'Trott': 'COGS', 'Fleischer': 'COGS'}
## Now, we define another dictionary with more info.
registrar_other = {'Styler': 'LING',
                   'Ellis': 'COGS',
                  'Rangel': 'COGS'}
## Finally, we "update" original registrar
registrar.update(registrar_other)
print(registrar)
{'Trott': 'COGS', 'Fleischer': 'COGS', 'Styler': 'LING', 'Ellis': 'COGS', 'Rangel': 'COGS'}
Check-in#
Recall that a dictionary cannot contain duplicate keys. What do you think would happen to original_dict if we ran the code below?
original_dict = {'a': 1, 'b': 3}
new_dict = {'a': 2}
original_dict.update(new_dict)
### What happens to original_dict['a']?
Updating with duplicate keys#
If we update a dictionary with another dictionary that contains overlapping keys, the new values replace the old values.
original_dict = {'a': 1, 'b': 3}
new_dict = {'a': 2}
original_dict.update(new_dict)
print(original_dict['a'])
2
Iterating through a dict#
Dictionaries are structured collections of key/value pairings.
As such, there are several ways to iterate (i.e., loop) through a dict:
- Iterating through a - listof keys (- .keys()).
- Iterating through a - listof values (- .values()).
- Iterating through a - listof key/value- tuples(- .items()).
Looping through keys with .keys()#
Each dictionary can be thought of as a list of keys; each key in turn maps onto some value.
We can retrieve that list of keys using dict_name.keys().
courses = {'CSS 1': 'Introduction to Programming',
          'CSS 2': 'Data and Model Programming',
          'CSS 100': 'Advanced Analytic Programming'}
courses.keys()
dict_keys(['CSS 1', 'CSS 2', 'CSS 100'])
This dict_keys object behaves like a list: we can index into it, loop through it, and so on.
for course in courses.keys():
    print(course)
CSS 1
CSS 2
CSS 100
Check-in#
How could we retrieve each value of the dict using keys()?
### Your code here
Retrieving values#
Because each key maps onto a value, we can simply use it to index into courses.
for course in courses.keys():
    ## Index into courses
    name = courses[course]
    print(name)
Introduction to Programming
Data and Model Programming
Advanced Analytic Programming
Looping through values with .values()#
We can also retrieve the values directly using dict_name.values().
courses.values()
dict_values(['Introduction to Programming', 'Data and Model Programming', 'Advanced Analytic Programming'])
for course_name in courses.values():
    print(course_name)
Introduction to Programming
Data and Model Programming
Advanced Analytic Programming
Looping through key/value pairings with .items()#
Dictionaries are, at their core, a list of key/value pairings.
- We can access each of these using - dict_name.items().
- items()returns a- listof- tuples:- The first element of each - tupleis the key.
- The second element of each - tupleis the value.
 
for item in courses.items():
    print(item)
('CSS 1', 'Introduction to Programming')
('CSS 2', 'Data and Model Programming')
('CSS 100', 'Advanced Analytic Programming')
Assignment “unpacking”#
- We can access each element of the - tupleusing indexing, e.g.,- item[0]or- item[1].
- However, sometimes it’s more convenient to unpack these elements directly in the - forloop itself.
for code, name in courses.items():
    print(code)
    print(name)
CSS 1
Introduction to Programming
CSS 2
Data and Model Programming
CSS 100
Advanced Analytic Programming
Converting back to a dict#
We can use the dict function to convert a list of items back to a dict.
items = courses.items()
print(items)
dict_items([('CSS 1', 'Introduction to Programming'), ('CSS 2', 'Data and Model Programming'), ('CSS 100', 'Advanced Analytic Programming')])
course_dict = dict(items)
print(course_dict)
{'CSS 1': 'Introduction to Programming', 'CSS 2': 'Data and Model Programming', 'CSS 100': 'Advanced Analytic Programming'}
Check-in: Looping through values#
Use the .items() function to loop through fruits_dict below. print out each item in a formatted string using format:
{fruit_name}: {price}.
fruits_dict = {'apple': 2, 'banana': 3}
### Your code here
Check-in: Debug#
Suppose someone writes a piece of code (see below) to loop through fruits_dict. Ultimately, they want to print out the price of each fruit.
However, they keep running into an error. Can you figure out what they’re doing wrong? And further, could you suggest a way to fix it?
### Why is this throwing an error?
for fruit in fruits_dict.values():
    print(fruits_dict[fruit])
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
Input In [59], in <cell line: 2>()
      1 ### Why is this throwing an error?
      2 for fruit in fruits_dict.values():
----> 3     print(fruits_dict[fruit])
KeyError: 2
Nested dictionaries#
A nested dictionary is a dictionary contained inside another dictionary, i.e., as a value.
In principle, there is no limit on how many nested dictionaries can be contained in a dict (besides memory capacity on one’s computer).
- A nested dictionary is useful when you want to store complex information in each entry. 
- So far, we’ve dealt mostly with very simple key/value entries. 
- But what if we wanted to represent more complicated information? 
Example, for each instructor in CSS (or COGS, etc.), store:
- username.
- Name.
- Courses(a- list).
- Department
- Title.
Check-in (conceptual)#
What would be a useful dict structure to represent information about instructors? For example, say we wanted to represent:
- username(e.g.,- sttrott)
- Name(e.g.,- Sean Trott)
- Courses(e.g.,- ['COGS 14A', ...])
- Department(e.g.,- COGS)
- Title(e.g.,- Assistant Teaching Professor)
A possible implementation#
One approach is to use nested dictionaries.
- At the top level, each instructor is represented by their - username.
- Each PID then maps onto a nested dictionary, which contains their - Name,- Email, and any other info we need.
instructors = {
    'sttrott': {'Name': 'Sean Trott',
                'Courses': ['COGS 14A', 'CSS 1', 'CSS 2'],
               'Title': 'Assistant Teaching Professor',
               'Department': 'COGS'},
    'sellis': {'Name': 'Shannon Ellis',
                'Courses': ['COGS 18', 'COGS 108', 'COGS 137'],
               'Title': 'Associate Teaching Professor',
               'Department': 'COGS'},
    'wstyler': {'Name': 'Will Styler',
                'Courses': ['LING 6', 'LING 101'],
               'Title': 'Director of CSS',
               'Department': 'LING'},
}
Indexing our nested dict#
We can index into this dict as we would normally. Note that now, the value is itself a dict.
instructors['sellis']
{'Name': 'Shannon Ellis',
 'Courses': ['COGS 18', 'COGS 108', 'COGS 137'],
 'Title': 'Associate Teaching Professor',
 'Department': 'COGS'}
Check-in#
How might we index the Title of a particular instructor? I.e., what if we wanted to find out the Title of sttrott?
### Your code here
Nested indices#
Indexing into a nested dictionary follows the same logic––we can chain together index statements to retrieve a particular value.
instructors['sttrott']['Title']
'Assistant Teaching Professor'
instructors['sttrott']['Department']
'COGS'
Check-in#
How would you retrieve the list of usernames (i.e., keys) in this dict?
Solution#
usernames = instructors.keys()
print(usernames)
dict_keys(['sttrott', 'sellis', 'wstyler'])
Conclusion#
This concludes our introduction to dictionaries.
As mentioned earlier, dictionaries are very widely used. They also help set the stage for a couple topics we’ll be discussing later on:
- Using - pandas.DataFrame.
Next time, we’ll discuss a few more common operations that we use with dictionaries, and get some more hands-on practice.
