Dictionaries!¶
Dictionaries are a completely different data structure from what we've seen so far. A dictionary is usually said "a mapping" type and they're different from the "sequences" we've worked with (lists, tuples).
A simple dictionary:
{
'name': 'Jane Doe',
'email': 'jane@rmotr.com',
'age': 27,
'city': 'San Jose',
'state': 'CA'
}
As you can see, a dictionary stores the values of a user, but with a corresponding "label" (name
, email
, age
, etc). The same information could have been stored in a list:
# 0 1 3 4 5
l = ['Jane Doe', 'jane@rmotr.com', 27, 'San Jose', 'CA']
l
l[1]
d = {
0: 'Jane Doe',
1: 'jane@rmotr.com',
2: 27,
3: 'San Jose',
4: 'CA'
}
But by looking at that list, how do you know what each fields represent? How do you know that San Jose
is the city and not their school?
Dictionaries solve this problem, they have a key (the label) for each value, which provides instant documentation.
Properties of dictionaries¶
- Unordered
- Mutable
- Key-Value pairs
- Keys must be unique
Constructing dictionaries¶
As you've seen, we use {}
to construct dictionaries. Dictionaries hare heterogeneous, we can mix key values:
{
'name': 'Jane',
19: 'some value',
(1, 1, 2): 'a tuple as a key?'
}
Even though we can use multiple different types of keys, we try to keep it simple and just use strings. Let's create our user dict again:
user = {
'name': 'Jane Doe',
'email': 'jane@rmotr.com',
'age': 27,
'city': 'San Jose',
'state': 'CA'
}
Accessing values:¶
user['name']
user['age']
Creating new values:¶
# country didn't exist
user['country'] = 'US'
user
print(user['country'])
What happens if we try to access a key that doesn't exist?¶
user['school']
An error is raised. Python is very strict when accessing dictionary keys. They must exist. There are two ways of fixing this:
Option 1: Checking if the key exists¶
'school' in user
'age' in user
if 'school' in user:
print(user['school'])
else:
print("Key `school` doesn't exist")
Option 2: Using the get
method:¶
The get
method will not fail if the key doesn't exist. It'll just return None
in that case.
user['school']
user.get('school') # this is None
print(user.get('school')) # when we print it we "see it"
user.get('email')
user.get('age', 30)
get
also accepts a "default" value in case the the key doesn't exist:
user.get('school', 'San Jose High School') # just in case, we provide a default value
user
Warning! the in
operator only checks for "keys":¶
'age' in user
'school' in user
user
"Jane Doe" in user
Accessing values¶
We can access only values of a dictionary with the values
method:
user.values()
Now we can ask if "Jane Doe" is within the collection of values:
"Jane Doe" in user.values()
Accessing only keys¶
As we have a values
method, there's also a keys
method that will retrieve only the keys:
user.keys()
Combining dictionaries¶
We can use the update
method to combine dictonaries:
user
school_info = {
'high school': 'San Jose High School',
'university': 'San Jose State University'
}
We "merge" school_info
into user
:
user.update(school_info)
And now user
contains:
user
all the info from both dicts. school_info
is still the same:
school_info
Deleting keys-values¶
del user['high school']
user
Trying to delete a key that doesn't exist also raises an exception:
high_school = user['high school']
del user['high school']
Let's restore high school back in place:
user['high school'] = school_info['high school']
Removing elements with pop
¶
del
removes the element and now it's completely lost. The pop
method will remove the element, but also return it, so we can store it in a variable for later usage:
user.pop('high school')
☝️ it was returned. I can try storing it in a variable:
uni = user.pop('university')
The key is no longer there:
user
user['name']
But I have the value stored in the uni
var:
uni
pop
also fails if the key doesn't exist:
user.pop('school')
But we can provide a "default" value that will prevent the exception:
user.pop('school', None)
user.pop('school', 'San Jose High School')
Iterating over dictionaries:¶
It's extremely simple (and convenient) to iterate over dictionaries. Check this out:
for key in user:
print(key)
As you can see, we're iterating by "key". We could access each value internally with that key:
for key in user:
value = user[key]
print('The key is "{}" and the value is "{}"'.format(key, value))
We can also rely on the keys
and values
methods:
for value in user.values():
print(value)
The wonderful world of items
❤️¶
So sometimes we need to iterate over BOTH keys and values. But the keys
method returns only keys and values
only values. The question is:
That's why we're going to use the amazing items()
method, it'll return BOTH keys and values:
for key, value in user.items():
print('The key is "{}" and the value is "{}"'.format(key, value))