Python 101: All About Dictionaries

The Python programming language has several built-in types that it supports. One of my favorites is the dictionary. A dictionary is a mapping object maps hashable values to arbitrary objects (source). Other languages call dictionaries “hash tables”. They are mutable objects that you can change whenever you want to, unlike tuples. A dictionary’s keys must be hashable or immutable, which means that you cannot use a list or another dictionary as a key. Note that dictionaries before Python 3.6 are not ordered. In Python 3.7, they changed the dict’s implementation so that it is now ordered.

In this article, we will take some time learning about some of the many things you can do with a dictionary.


Creating Dictionaries

A dictionary is a key:value pair. In Python, these key:value pairs are enclosed inside of curly braces with commas between each pair. Creating dictionaries in Python is really easy. Here are the three ways to create a dictionary:

>>> my_dict = {}
>>> my_other_dict = dict()
>>> my_other_other_dict = {1: 'one', 2: 'two', 3: 'three'}

In the first example, we create an empty dictionary by just assigning our variable to a pair of empty curly braces. You can also create a dictionary object by calling Python’s built-in dict() keyword. I have seen some people mention that calling dict() is slightly slower than just doing the assignment operator. The last example shows how to create a dictionary with some predefined key:value pairs. You can have dictionaries that contain mappings of various types, including mapping to functions or objects. You can also nest dictionaries and lists inside your dictionaries!


Accessing Dictionary Values

Accessing the values held in a dictionary is quite simple. All you need to do is pass a key to you dict inside of square braces. Let’s take a look at an example:

>>> my_other_other_dict = {1: 'one', 2: 'two', 3: 'three'}
>>> my_other_other_dict[1]
'one'

What happens if you ask the dictionary for a key that doesn’t exist? You will receive a KeyError, like so:

>>> my_other_other_dict[4]
Traceback (most recent call last):
  Python Shell, prompt 5, line 1
KeyError: 4

This error is telling us that there is no key called “4” in the dictionary. If you want to avoid this error you can use the dict’s get() method:

>>> my_other_other_dict.get(4, None)
None

The get() method will ask the dictionary if it contains the specified key (i.e. 4) and if it doesn’t, you can specify what value to return. In this example, we return a None type if the key does not exist.

You can also use Python’s in operator to check if a dictionary contains a key as well:

>>> key = 4
>>> if key in my_other_other_dict:
        print('Key ({}) found'.format(key))
    else:
        print('Key ({}) NOT found!'.format(key))
 
Key (4) NOT found!

This will check if the key, 4, is in the dictionary and print the appropriate response. In Python 2, the dictionary also had a has_key() method that you could use in addition to using the in operator. However, has_key() was removed in Python 3.


Updating Keys

As you’ve probably already guessed, updating the value that a key is pointing to is extremely easy. Here’s how:

>>> my_dict = {}
>>> my_dict[1] = 'one'
>>> my_dict[1]
'one'
>>> my_dict[1] = 'something else'
>>> my_dict[1]
'something else'

Here we create an empty dictionary instance and then add one element to the dictionary. Then we point that key, which is the integer 1 (one) in this case, to another string value.


Removing Keys

There are two ways to remove key:value pairs from a dictionary. The first that we will cover is the dictionary’s pop() method. Pop will check if the key is in the dictionary and remove it if it is there. If the key is not in there, you will receive a KeyError. You can actually suppress the KeyError by passing in a second argument, which is the default return value.

Let’s take a look at a couple of examples:

>>> my_dict = {}
>>> my_dict[1] = 'something else'
>>> my_dict.pop(1, None)
'something else'
>>> my_dict.pop(2)
Traceback (most recent call last):
  Python Shell, prompt 15, line 1
KeyError: 2

Here we create a dictionary and add an entry. Then we remove that same entry using the pop() method. You will note that we also set the default to None so that if the key did not exist, the pop method would return None. In the first case, the key did exist, so it returned the value of the item it removed or popped.

The second example demonstrates what happens when you attempt to call pop() on a key that is not in the dictionary.

The other way to remove items from dictionaries is to use Python’s built-in del:

>>> my_dict = {1: 'one', 2: 'two', 3: 'three'}
>>> del my_dict[1]
>>> my_dict
>>>  {2: 'two', 3: 'three'}

This will delete the specified key:value pair from the dictionary. If the key isn’t in the dictionary, you will receive a KeyError. This is why I actually recommend the pop() method since you don’t need a try/except wrapping pop() as long as you supply a default.


Iterating

The Python dictionary allows the programmer to iterate over its keys using a simple for loop. Let’s take a look:

>>> my_dict = {1: 'one', 2: 'two', 3: 'three'}
>>> for key in my_dict:
       print(key)
1
2
3

Just a quick reminder: Python dictionaries are unordered, so you might not get the same result when you run this code. One thing I think needs mentioning at this point is that Python 3 changed things up a bit when it comes to dictionaries. In Python 2, you could call the dictionary’s keys() and values() methods to return Python lists of keys and values respectively:

# Python 2
>>> my_dict = {1: 'one', 2: 'two', 3: 'three'}
>>> my_dict.keys()
[1, 2, 3]
>>> my_dict.values()
['one', 'two', 'three']
>>> my_dict.items()
[(1, 'one'), (2, 'two'), (3, 'three')]

But in Python 3, you will get views returned:

# Python 3
>>> my_dict = {1: 'one', 2: 'two', 3: 'three'}
>>> my_dict.keys()
>>> dict_keys([1, 2, 3])
>>> my_dict.values()
>>> dict_values(['one', 'two', 'three'])
>>> my_dict.items()
dict_items([(1, 'one'), (2, 'two'), (3, 'three')])

In either version of Python, you can still iterate over the result:

for item in my_dict.values():
    print(item)
    
one
two
three

The reason is that both lists and views are iterable. Just remember that views are not indexable, so you won’t be able to do something like this in Python 3:

>>> my_dict.values()[1]

This will raise a TypeError.

Python has a lovely library called collections that contains some neat subclasses of the dictionary. We will be looking at the defaultdict and the OrderDict in the next two sections.


Default Dictionaries

There is a really handy library called collections that has a defaultdict module in it. The defaultdict will accept a type as its first argument or default to None. The argument we pass in becomes a factory and is used to create the values of the dictionary. Let’s take a look at a simple example:

from collections import defaultdict

sentence = "The red for jumped over the fence and ran to the zoo"
words = sentence.split(' ')

d = defaultdict(int)
for word in words:
    d[word] += 1

print(d)

In this code, we pass the defaultdict an int. This allows us count the words of a sentence in this case. Here’s the output of the code above:

defaultdict(, 
            {'and': 1, 
             'fence': 1, 
             'for': 1, 
             'ran': 1, 
             'jumped': 1,
             'over': 1, 
             'zoo': 1, 
             'to': 1, 
             'The': 1, 
             'the': 2, 
             'red': 1})

As you can see, each word was found only once except for the string “the”. You will note that it is case-sensitive as “The” was only found once. We could probably make this code a bit better if we had changed the case of the strings to lower.


Ordered Dictionaries

The collections library also let’s you create dictionaries that remember their order of insertion. This is known as the OrderedDict. Let’s take a look at an example from one of my previous articles:

>>> from collections import OrderedDict
>>> d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}
>>> new_d = OrderedDict(sorted(d.items()))
>>> new_d
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])
>>> for key in new_d:
...     print (key, new_d[key])
... 
apple 4
banana 3
orange 2
pear 1

Here we create a regular dict, sort it and pass that to our OrderedDict. Then we iterate over our OrderedDict and print it out. You will note that it prints out in alphabetical order because that is how we inserted the data. This is something you likely wouldn’t see if you just iterated over the original dictionary.

There is one other dictionary subclass in the collections module called the Counter that we won’t be covering here. I encourage you to check that out on your own.


Wrapping Up

We’ve covered a lot of ground in this article. You should now know basically all you need to know about using dictionaries in Python. You have learned several methods of creating dictionaries, adding to them, updating their values, removing keys and even some of the alternate subclasses of the dictionary. I hope you’ve found this useful and that you will find many great uses for dictionaries in your own code soon!


Related Reading

4 thoughts on “Python 101: All About Dictionaries”

  1. Recently found your blog, and I love it. I’m working my way through Python 101 now (the interactive version) and I really enjoy the style. Keep up the good work 🙂

  2. I’m glad you’ve found it useful. I am also happy to know you are enjoying the interactive course. Let me know if you have any issues or questions.

  3. Since python 3.6, dictionaries preserve insertion order, so you’ll get the same result if you replace OrderedDict() by dict().

Comments are closed.