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
dict
cannot 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
str
orint
); they can’t be alist
.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 anotherdict
.
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 alist
) 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
list
of keys (.keys()
).Iterating through a
list
of values (.values()
).Iterating through a
list
of key/valuetuples
(.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 alist
oftuples
:The first element of each
tuple
is the key.The second element of each
tuple
is 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
tuple
using indexing, e.g.,item[0]
oritem[1]
.However, sometimes it’s more convenient to unpack these elements directly in the
for
loop 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
(alist
).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 username
s (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.