Dictionaries

Like a list, a dictionary, or dict, is a collection of values. Dictionaries consist of several key-value pairs. Each pair has a key which is used to access the value associated with it. The key in a dictionary is much like an index in a list, but whereas an index must be an integer, a key can be of many different data types.

Dictionaries are created using the following syntax:

my_dict = {key1:value1, key2:value2, ..., keyN:valueN}

Basic Dictionary Operations

The cell below defines a simple dictionary that is used to store salary information for employees.

salary_dict = {'Anna':43700, 'Beth': 50250}

print(salary_dict)
{'Anna': 43700, 'Beth': 50250}

We can access individual values of the dictionary using the associated keys.

print(salary_dict['Anna'])
print(salary_dict['Beth'])
43700
50250

We can add new key-value pairs to a dictionary as follows:

salary_dict['Craig'] = 47600
salary_dict['Drew'] = 37400

print(salary_dict)
{'Anna': 43700, 'Beth': 50250, 'Craig': 47600, 'Drew': 37400}

We can also update values in a dictionary.

salary_dict['Drew'] = 39800
print(salary_dict)
{'Anna': 43700, 'Beth': 50250, 'Craig': 47600, 'Drew': 39800}

We can delete entries from a dictionary using the del keyword.

del salary_dict['Craig']
print(salary_dict)
{'Anna': 43700, 'Beth': 50250, 'Drew': 39800}

We can use the len() function on dictionaries to determine the number of values that they contain.

print(len(salary_dict))
3

Dictionary Methods

Each dictionary come equipped with methods that can be used to access its keys, its values, or both. We will now explore each of the following methods:

  • The keys() method of a dictionary returns a collection of the keys for items that dictionary.

  • The values() method of a dictionary returns a collection of the values for items in that dictionary.

  • The items() method of a dictionary returns a collection of the key/value tuples for items in that dictionary.

We will illustrate the use of these methods in the cell below.

Dictionary elements are not ordered, and so dictionaries don’t allow for slicing. You can, however, loop over the elements of a dictionary.

print(salary_dict.keys())
print(salary_dict.values())
print(salary_dict.items())
dict_keys(['Anna', 'Beth', 'Drew'])
dict_values([43700, 50250, 39800])
dict_items([('Anna', 43700), ('Beth', 50250), ('Drew', 39800)])

The objects returned by the keys(), values(), and items() methods are not lists. Each method instead returns an object with a type specific to that function (dict_keys, dict_values, and dict_items). We can convert these objects to list using the list() function, if necessary. We can also use a for loop to iterate over these objects without first converting them to lists.

In the cell below, the values() in a loop to display the values stored in our dictionary.

for v in salary_dict.values():
    print(v)
43700
50250
39800

The values() method gives us no way of accessing the keys associated with individual values. If we want to display both keys and values, we can use keys() in a loop to iterate over the keys, displaying each key along with the value associated with it. We display the results using an f-string.

for k in salary_dict.keys():
    print(f'{k}: {salary_dict[k]}')
Anna: 43700
Beth: 50250
Drew: 39800

We can obtain the same results as above by instead using the items() method. When iterate over the dictionary items, we are provided a tuple of key values pairs at each step. We can unpack this tuple into separate variables. This saves us from having to use the keys to look up the associated values.

for k, v in salary_dict.items():
    print(f'{k}: {v}')
Anna: 43700
Beth: 50250
Drew: 39800

Lookup Tables

One common application of dictionaries is to create lookup tables. Let’s say that you have several objects, and each one has a unique identifier assigned to it. Assume that your code has to frequently look up characteristics of the objects based on their identifier. This can be easily done with a dictionary.

The code below illustrates how you might use a dictionary to store ID-Name pairs in a student database.

student_lookup = {
    601814: 'Brown, Mary',
    716978: 'Green, John',
    617945: 'Jones, Lana',
    863794: 'Smith, Hank',
    816773: 'Green, John'
}

We will now use the lookup table to find the names of two students based on their student ID numbers.

print(student_lookup[617945])
print(student_lookup[816773])
Jones, Lana
Green, John

Using Dictionaries to Store Structured Data

The values in a dictionary can be lists. This is convenient if we would like use a dictionary to store records of some type. In this case, we can imagine the keys of the dictionary as indicating columns in a table.

employee_dict = {
    'EID': [103, 105, 101, 106, 108],
    'Name': ['Anna', 'Beth', 'Craig', 'Drew', 'Emma'],
    'Salary': [43700, 50250, 47600, 39800, 38750],
    'Rank': [2, 1, 1, 2, 3]
}

Each key in the dictionary represents a particular type of information. The associated value is a list that represents this piece of information for each record (row) in our table.

print(employee_dict['Name'])
['Anna', 'Beth', 'Craig', 'Drew', 'Emma']

If we want to see the information for a specific entry in the table, we can provide the same index to each of the lists stored within the dictionary.

print('EID   Name    Salary  Rank')
print('---------------------------------')
for i in range(len(employee_dict['Name'])):
    e = employee_dict['EID'][i]
    n = employee_dict['Name'][i] 
    s = employee_dict['Salary'][i]
    r = employee_dict['Rank'][i]
    
    print(f'{e:<6}{n:<8}{s:<8}{r:>4}')
    
EID   Name    Salary  Rank
---------------------------------
103   Anna    43700      2
105   Beth    50250      1
101   Craig   47600      1
106   Drew    39800      2
108   Emma    38750      3

One limitation of using a dictionary in this way is that there is no convenient way to extract all of the information related to a single individual at once.

As an alternate approach to using dictionaries to store structured data, we can store individual records in dictionaries, and then collect them together into a list (or another dictionary). In the setup, we could imaging the dictionaries as representing rows in a table rather than columns.

my_cats = [
    {
        'name':'Luna', 
        'birthplace':'State College, PA', 
        'weight':14.3, 
        'age':11, 
        'characteristics':['lazy', 'hungry', 'cranky']
    },
    {
        'name':'Garbanzo', 
        'birthplace':'State College, PA',
        'weight':8.9,
        'age':11,
        'characteristics':['talkative', 'friendly', 'skittish']
    },
    {
        'name':'Cauchy',
        'birthplace':'St. Louis, MO',
        'weight':10.6,
        'age':4,
        'characteristics':['insane', 'destructive', 'scoundrel']
    }
]

We will display the contents of the list above by looping over the dictionaries contained inside of it. We will use an f-string to print the values stored in each of the dictionaries.

print(f'{"Name":<12}{"Birthplace":<20}{"Weight":>6}{"Age":>6}   {"Characteristics":<10}')
print('-'*85)
for cat in my_cats:
        
    n = cat['name'] 
    b = cat['birthplace'] 
    w = cat['weight'] 
    a = cat['age'] 
    c = cat['characteristics'] 
    
    print(f'{n:<12}{b:<20}{w:>6}{a:>6}   {str(c):<10}')
    
Name        Birthplace          Weight   Age   Characteristics
-------------------------------------------------------------------------------------
Luna        State College, PA     14.3    11   ['lazy', 'hungry', 'cranky']
Garbanzo    State College, PA      8.9    11   ['talkative', 'friendly', 'skittish']
Cauchy      St. Louis, MO         10.6     4   ['insane', 'destructive', 'scoundrel']