Dictionaries

Published

2023-08-02

Introduction to dictionaries

So far, we’ve seen tuples, lists, and strings as ordered collections of objects. We’ve also seen how to access individual elements within a list, tuple, or string by the element’s index.

>>> lst = ['rossi', 'agostini', 'marquez', 'doohan', 'lorenzo']
>>> lst[0]
'rossi'
>>> lst[2]
'marquez'
>>> t = ('hearts', 'clubs', 'diamonds', 'spades')
>>> t[1]
'clubs'

This is all well and good, but sometimes we’d like to be able to use something other than a numeric index to access elements.

Consider conventional dictionaries which we use for looking up the meaning of words. Imagine if such a dictionary used numeric indices to look up words. Let’s say we wanted to look up the word “pianist.” How would we know its index? We’d have to hunt through the dictionary to find it. Even if all the words were in lexicographic order, it would still be a nuisance having to find a word this way.

The good news is that dictionaries don’t work that way. We can look up the meaning of the word by finding the word itself. This is the basic idea of dictionaries in Python.

A Python dictionary, simply put, is a data structure which associates keys and values. In the case of a conventional dictionary, each word is a key, and the associated definition or definitions are the values.

Here’s how the entry for “pianist” appears in my dictionary:1

pianist n. a person who plays the piano, esp.  a skilled or professional performer

Here pianist is the key, and the rest is the value. We can write this, with some liberty, as a Python dictionary, thus:

>>> d = {'pianist': "a person who plays the piano, " \
...      "esp. a skilled or professional performer"}

The entries of a dictionary appear within braces {}. The key/value pairs are separated by a colon, thus: <key>: <value>, where <key> is a valid key, and <value> is a valid value.

We can look up values in a dictionary by their key. The syntax is similar to accessing elements in a list or tuple by their indices.

>>> d['pianist']
'a person who plays the piano, esp. a skilled or 
 professional performer'

Like lists, dictionaries are mutable. Let’s add a few more words to our dictionary. To add a new entry to a dictionary, we can use this approach:

>>> d['cicada'] = "any of a family of large flylike " \
...               "insects with transparent wings" 
>>> d['proclivity'] = "a natural or habitual tendency or " \
...                   "inclination, esp. toward something " \
...                   "discreditable"
>>> d['tern'] = "any of several sea birds, related to the " \
...             "gulls, but smaller, with a more slender " \
...             "body and beak, and a deeply forked tail"
>>> d['firewood'] = "wood used as fuel"
>>> d['holophytic'] = "obtaining nutrition by photosynthesis, " \
...                   "as do green plants and some bacteria"

Now let’s inspect our dictionary.

>>> d
{'pianist': 'a person who plays the piano, esp. a skilled or 
professional performer', 'cicada': 'any of a family of large 
flylike insects with transparent wings', 'proclivity': 'a 
natural or habitual tendency or inclination, esp. toward 
something discreditable', 'tern': 'any of several sea birds, 
related to the gulls, but smaller, with a more slender body 
and beak, and a deeply forked tail', 'firewood': 'wood used 
as fuel', 'holophytic': 'obtaining nutrition by photosynthesis, 
as do green plants and some bacteria'}

We see that our dictionary consists of key/value pairs.

key value
'pianist' 'a person who plays the piano, esp. a skilled or professional performer'
'cicada' 'any of a family of large flylike insects with transparent wings'
'proclivity' 'a natural or habitual tendency or inclination, esp. toward something discreditable'
'tern' 'any of several sea birds, related to the gulls, but smaller, with a more slender body and beak, and a deeply forked tail'
'firewood' 'wood used as fuel'
'holophytic' 'obtaining nutrition by photosynthesis, as do green plants and some bacteria'

We can look up any value with its key.

>>> d['tern']
'any of several sea birds, related to the gulls, but smaller, 
with a more slender body and beak, and a deeply forked tail' 

If we try to access a key which does not exist, this results in a KeyError.

>>> d['bungalow']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'bungalow'

This is a new type of exception we haven’t seen until now.

We may overwrite a key with a new value.

>>> d = {'France': 'Paris',
...      'Mali': 'Bamako',
...      'Argentina': 'Buenos Aires',
...      'Thailand': 'Bangkok',
...      'Australia': 'Sydney'}  # oops!
>>> d['Australia'] = 'Canberra'  # fixed!

So far, in the examples above, keys and values have been strings. But this needn’t be the case.

There are constraints on the kinds of things we can use as keys, but almost anything can be used as a value.

Here are some examples of valid keys:

>>> d = {(1, 2): 'My key is the tuple (1, 2)',
         100: 'My key is the integer 100',
         'football': 'My key is the string "football"'}

Values can be almost anything—even other dictionaries!

>>> students = {'eporcupi': {'name': 'Egbert Porcupine',
...                          'major': 'computer science',
...                          'gpa': 3.14},
...             'epickle':  {'name': 'Edwina Pickle',
...                          'major': 'biomedical engineering',
...                          'gpa': 3.71},
...             'aftoure':  {'name': 'Ali Farka Touré',
...                          'major': 'music',
...                          'gpa': 4.00}}
>>> students['aftoure']['major']
'music'
>>> recipes = {'bolognese': ['beef', 'onion', 'sweet pepper', 
...                          'celery', 'parsley', 'white wine',
...                          'olive oil', 'garlic', 'milk',
...                          'black pepper', 'basil', 'salt'],
...            'french toast': ['baguette', 'egg', 'milk',
...                             'butter', 'cinnamon', 
...                             'maple syrup'],
...            'fritters': ['potatoes', 'red onion', 'carrot',
...                         'red onion', 'garlic', 'flour',
...                         'paprika', 'marjoram', 'salt',
...                         'black pepper', 'canola oil']}
>>> recipes['french toast']
['baguette', 'egg', 'milk', 'butter', 'cinnamon', 'maple syrup']
>>> recipes['french toast'][-1]
'maple syrup'
>>> coordinates = {'Northampton': (42.5364, -70.9857),
...                'Kokomo': (40.4812, -86.1418),
...                'Boca Raton': (26.3760, -80.1223),
...                'Sausalito': (37.8658, -122.4980),
...                'Amarillo': (35.1991, -101.8452),
...                'Fargo': (46.8771, -96.7898)}
>>> lat, lon = coordinates['Fargo']  # tuple unpacking
>>> lat
46.8771
>>> lon
-96.7898

Restrictions on keys

Keys in a dictionary must be hashable. In order for an object to be hashable, it must be immutable, or if it is an immutable container of other objects (for example, a tuple) then all the objects contained must also be immutable. Valid keys include objects of type int, float (OK, but a little strange), str, bool (also OK, but use cases are limited). Tuples can also serve as keys as long as they do not contain any mutable objects.

>>> d = {0: 'Alexei Fyodorovich', 1: 'Dmitri Fyodorovich',
...      2: 'Ivan Fyodorovich', 3: 'Fyodor Pavlovich', 
...      4: 'Agrafena Alexandrovna', 5: 'Pavel Fyodorovich',
...      6: 'Zosima', 7: 'Katerina Ivanovna'}
>>> d = {True: 'if porcupines are blue, then the sky is pink',
...      False: 'chunky monkey is the best ice cream'}
>>> d = {'Phelps': 23, 'Latynina': 9, 'Nurmi': 9, 'Spitz': 9, 
...      'Lewis': 9, 'Bjørgen': 8}

However, these are not permitted:

>>> d = {['hello']: 'goodbye'}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> d = {(0, [1]): 'foo'}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

Testing membership

Just as with lists we can use the keyword in to test whether a particular key is in a dictionary.

>>> d = {'jane': 'maine', 'wanda': 'new hampshire', 
...      'willard': 'vermont', 'simone': 'connecticut'}
>>> 'wanda' in d
True
>>> 'dobbie' in d
False
>>> 'dobbie' not in d
True

Original author: Clayton Cafiero < [given name] DOT [surname] AT uvm DOT edu >

No generative AI was used in producing this material. This was written the old-fashioned way.

This material is for free use under either the GNU Free Documentation License or the Creative Commons Attribution-ShareAlike 3.0 United States License (take your pick).

Footnotes

  1. Webster’s New World Dictionary of the American Language, Second College Edition.↩︎