7.1. Introduction to Dictionaries

The last standard type to add to our repertoire is the dictionary, the sole mapping type in Python. A dictionary is mutable and is another container type that can store any number of Python objects, including other container types. What makes dictionaries different from sequence type containers like lists and tuples is the way the data is stored and accessed.

Sequence types use numeric keys only (numbered sequentially as indexed offsets from the beginning of the sequence). Mapping types may use most other object types as keys, strings being the most common. Unlike sequence type keys, mapping keys are often, if not directly, associated with the data value that is stored. But because we are no longer using “sequentially-ordered” keys with mapping types, we are left with an unordered collection of data. As it turns out, this does not hinder our use because mapping types do not require a numeric value to index into a container to obtain the desired item. With a key, you are “mapped” directly to your value, hence the term “mapping type.” The most common data structure that maps keys with associated values are hash tables.

CORE NOTE: What are hash tables and how do they relate to dictionaries?

Sequence types use sequentially-ordered numeric keys as index offsets to store your data in an array format. The index number usually has nothing to do with the data value that is being stored. There should also be a way to store data based on another, associated value such as a string. We do this all the time in everyday living. You file people's phone numbers in your address book based on last name, you add events to your calendar or appointment book based on date and time, etc. For each of these examples, an associated value to a data item was your key.

Hash tables are a data structure that does exactly what we described. They store each piece of data, called a value, based on an associated data item, called a key. Together, these are known as key-value pairs. The hash table algorithm takes your key, performs an operation on it, called a hash function, and based on the result of the calculation, chooses where in the data structure to store your value. Where any one particular value is stored depends on what its key is. Because of this randomness, there is no ordering of the values in the hash table. You have an unordered collection of data.

The only kind of ordering you can obtain is by key. You can request a dictionary's keys, which is returned to you as a list. From there, you can call the list's sort() method to order that data set. This is only one type of ordering you can perform on your keys. In any case, once you have determined that the set of keys is “sorted” to your satisfaction, their associated values may be retrieved from the dictionary. Hash tables generally provide good performance because lookups occur fairly quickly once you have a key. For a sequential access data structure, you must march down to the correct index location and then retrieve the value. Naturally, performance is based on the type of hash function used.


Python dictionaries are implemented as resizeable hash tables. If you are familiar with Perl, then we can say that dictionaries are similar to Perl's associative arrays or hashes.

We will now take a closer look at Python dictionaries. The syntax of a dictionary entry is key:value. Also, dictionary entries are enclosed in braces ( { } ).

How to Create and Assign Dictionaries

Creating dictionaries simply involves assigning a dictionary to a variable, regardless of whether the dictionary has elements or not:

>>> dict1 = {}
>>> dict2 = {'name': 'earth', 'port': 80}
>>> dict1, dict2
({}, {'port': 80, 'name': 'earth'})

How to Access Values in Dictionaries

To access dictionary elements, you use the familiar square brackets along with the key to obtain its value:

>>> dict2['name']
'earth'
>>>
>>> print 'host %s is running on port %d' % 
…    (dict2['name'], dict2['port'])
host earth is running on port 80

Dictionary dict1 is empty while dict2 has two data items. The keys in dict2 are 'name' and 'port', and their associated value items are 'earth' and 80, respectively. Access to the value is through the key, as you can see from the explicit access to the 'name' key.

If we attempt to access a data item with a key which is not part of the dictionary, we get an error:

>>> dict2['server']
Traceback (innermost last):
  File "<stdin>", line 1, in ?
KeyError: server

In this example, we tried to access a value with the key 'server' which, as you know, does not exist from the code above. The best way to check if a dictionary has a specific key is to use the dictionary's has_key() method. We will introduce all of a dictionary's methods below. The Boolean has_key() method will return a 1 if a dictionary has that key and 0 otherwise.

>>> dict2.has_key('server')
0
>>> dict2.has_key('name')
1
>>> dict2['name']
'earth'

Once the has_key() method has given the okay, meaning that a key exists, then you can access it without having to worry about getting the KeyError, similar to what happened above. Let us take a look at another dictionary example, using keys other than strings:

>>> dict3 = {}
>>> dict3[1] = 'abc'
>>> dict3['1'] = 3.14159
>>> dict3[3.2] = 'xyz'
>>> dict3
{3.2: 'xyz', 1: 'abc', '1': 3.14159}

Rather than adding each key-value pair individually, we could have also entered all the data for dict3 at the same time:

dict3 = { 3.2: 'xyz', 1: 'abc', '1': 3.14159 }

Creating the dictionary with a set key-value pair can be accomplished if all the data items are known in advance (obviously). The goal of the examples using dict3 is to illustrate the variety of keys that you can use. If we were to pose the question of whether a key for a particular value should be allowed to change, you would probably say, “No.” Right?

Not allowing keys to change during execution makes sense if you think of it this way: Let us say that you created a dictionary element with a key and value. Somehow during execution of your program, the key changed, perhaps due to an altered variable. When you went to retrieve that data value again with the original key, you got a KeyError (since the key changed), and you had no idea how to obtain your value now because the key had somehow been altered. Because of this reason, keys must be immutable, so numbers and strings are fine, but lists and other dictionaries are not. (See Section 7.5.2 for why keys must be immutable.)

How to Update Dictionaries

You can update a dictionary by adding a new entry or element (i.e., a key-value pair), modifying an existing entry, or deleting an existing entry (see below for more details on removing an entry).

>>> dict2['name'] = 'venus'          # update existing entry
>>> dict2['port'] = 6969             # update existing entry
>>> dict2['arch'] = 'sunos5'         # add new entry
>>>
>>> print 'host %(name)s is running on port %(port)d' % dict2
host venus is running on port 6969

If the key does exist, then its previous value will be overridden by its new value. The print statement above illustrates an alternative way of using the string format operator ( % ), specific to dictionaries. Using the dictionary argument, you can shorten the print request somewhat because naming of the dictionary occurs only once, as opposed to occurring for each element using a tuple argument.

You may also add the contents of an entire dictionary to another dictionary by using the update() built-in method. We will introduce this methods later on in this chapter in Section 7.4.

How to Remove Dictionary Elements and Dictionaries

Removing an entire dictionary is not a typical operation. Generally, you either remove individual dictionary elements or clear the entire contents of a dictionary. However, if you really want to “remove” an entire dictionary, use the del statement (introduced in Section 3.5.6). Here are some deletion examples for dictionaries and dictionary elements:

del dict1['name']         # remove entry with key 'name'

dict1.clear()             # remove all entries in dict1

del dict1                 # delete entire dictionary

CORE NOTE: Why is there no dict.remove() method as there is a list.remove()?

You may recall that there are two ways to delete an entry from a list, using the del statement or using the list. remove() method. Then you must be wondering, why do lists have a remove entry method but not dictionaries? One simple answer is that to remove a element from a list is a two-step effort. You must first find the index (a.k.a. the key) where the data item is located and then call the del statement. The remove() method was written to perform both steps, leaving the programmer with a single step. With dictionaries, you already have the key; there is no need to perform a lookup. You just call del once. Creating a dictionary method to remove an entry will provide you with a functional interface.


..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset