Dictionaries - Learn Python 3 - Snakify

Lesson 11. Dictionaries


1. Dictionaries

Normal lists (arrays) are usually a set of numbered elements, so if you want to make a reference to any list item, you must specify its number. The number of element in the list uniquely identifies the item itself. But identification numbers are not always convenient. For example, the routes of trains in Russia use letters and numbers as identification code (number and one digit), also numerical-alphabetic code identifies the flights, i.e. information about flights, trains or aircraft ID should be stored not as a number but as a text string.

Data structure, which allows to use an arbitrary type of index instead of numerical, is called dictionary or associative array. The corresponding data structure in Python is called dict.

Consider a simple example. Get the dictionary Capitals, where index is the name of the country, and the value — the name of the capital of this country. Now for a row with the name of the country we can easily idenify its capital.

# Create empty dict Capitals
Capitals = dict()

# Fill it with some values
Capitals['Russia'] = 'Moscow'
Capitals['Ukraine'] = 'Kiev'
Capitals['USA'] = 'Washington'

Countries = ['Russia', 'France', 'USA', 'Russia']

for country in Countries:
  # For each country from the list check to see whether it is in the dictionary Capitals
    if country in Capitals:
        print('The capital of ' + country + ' is ' + Capitals[country])
    else:
        print('The capital of ' + country + ' is unknown')

So, each element of the dictionary consists of two objects: key and values. In our example key is the country name and the value is the name of the capital. The key identifies the element of the dictionary, the value is the data corresponding to the given key. Key values are unique, i. e. there can't be two identical keys in the dictionary.

We are used to dictionaries around us, the usual paper dictionaries (defining, monolingual, bilingual). For defining dictionary the key is the word (the title of the article), and the value is the article itself, and in order to access the article, you must specify the word-key.

A telephone directory is another example of dictionary data structure. In this case, the key is the name and value is the phone number. For both the dictionary and telephone directory it's easy to find an element of the dictionary with a given key (e.g., if records are stored in alphabetical order of the keys, you can easily find your key with a binary search), but if the key is unknown, and we know only the value, the search for the element with the given value may require a consistent view of all elements of the dictionary.

An important feature of the associative array is that it is dynamic, i. e. you can add new elements with any keys and delete the existing elements. The amount of memory used is proportional to the size of the associative array. Access to the elements of an associative array is slower than for ordinary arrays, but still pretty quickly.

In Python, the key can be any immutable (not changeable) data type: integers and real numbers, strings, tuples. The key in the dictionary may not be a set, but may be an element of type frozenset: a special data type analogue of a type set that cannot be modified after creation. The dictionary element value can be any data type, including modifiable.

2. Applying dictionaries

Dictionaries are used in the following cases:

  • to count the number of some objects. In this case, you need to make a dictionary where keys are objects and values are amounts.
  • the storage of any data associated with the object. The keys are objects, the values are associated data. For example, if you want to determine month's sequence number by its name, you can do it using the dictionary Num['January'] = 1; Num['February'] = 2; ....
  • setting the correspondence between the objects (for instance, «the parent—descendant»). The key is the object and the value is the corresponding object.
  • if you need a simple array, but the maximum value of the index of the element is very large, though not all the possible indexes will be used (so-called "sparse array"), you can use associative array to save memory.

    An empty dictionary can be created using the function dict() or an empty pair of curly braces {} (this is actually the reason the curly braces cannot be used to create an empty set). To create a dictionary with some set of initial values, you can use the following constructions:

    Capitals = {'Russia': 'Moscow', 'Ukraine': 'Kiev', 'USA': 'Washington'}
    Capitals = dict(RA = 'Moscow', Ukraine = 'Kiev', USA = 'Washington')
    Capitals = dict([("Russia", "Moscow"), ("Ukraine", "Kiev"), ("USA", "Washington")])
    Capitals = dict(zip(["Russia", "Ukraine", "USA"], ["Moscow", "Kiev", "Washington"]))
    print(Capitals)

    The first two methods can only be used to create small dictionaries by listing all their elements. In addition, in the second method, the keys are passed as named parameters of dict, so in this case, the keys can only be strings, and only correct identificators. In the third and fourth case, you can create large dictionaries, if transferred arguments are a ready-made list, which can be obtained not only from by listing all the elements, but are built in any other way during the execution of the program. In the third way the function dict needs to recieve a list where each element is a tuple of two elements: key and value. The fourth method uses the function zip, which needs to recieve two lists of equal length: a list of keys and list of values.

  • 3. Working with dictionary items

    Basic operation: getting value of the element by its key. It is written exactly as for lists: A[key]. If there is no element with specified key in the dictionary it raises the exception KeyError.

    Another way to define the value based on a key is a method get: A.get(key). If there is no element with the key get in the dictionary, it returns None. In the form with two arguments A.get(key, val) method returns val, if an element with the key key is not in the dictionary.

    To check if an element belongs to a dictionary operations in and not in are used, same as for sets.

    To add a new item to the dictionary you just need to assign it with some value: A[key] = value.

    To remove an item from the dictionary you can use del A[key] (operation raises an exception KeyError if there is no such key in the dictionary.) Here are two safe ways to remove an item from the dictionary.

    A = {'ab' : 'ba', 'aa' : 'aa', 'bb' : 'bb', 'ba' : 'ab'}
    
    key = 'ac'
    if key in A:
        del A[key]
    
    try:
        del A[key]
    except KeyError:
    	print('There is no element with key "' + key + '" in dict')
    print(A)

    In the first case, we preliminary check the presence of an element, then we catch and handle the exception.

    Another way to remove an item from the dictionary is the method pop: A.pop(key). This method returns the value of the removed element and if the element with the given key is not in the dictionary, an exception is raised. If the method pop receives a second parameter, than for the missing element it will return the value of this parameter. This allows to organize safely the removal of the element from the dictionary: A.pop(key, None).

    4. Iterating dictionary

    You can easily iterate through the keys of all items in the dictionary:

    A = dict(zip('abcdef', list(range(6))))
    for key in A:
        print(key, A[key])

    The following methods return representation of the elements of the dictionary. The representations are similar to sets, but they change, if you change the values of the elements. Method keys returns a representation of the keys of all elements, values returns a representation of all values, and the method items returns a representation of all pairs (tuples) of keys and values.

    Thus, for a quick check whether the value val is among all the values of the dictionary A you should use boolean condition val in A.values(). To loop through keys and variables, you can do the following:

    A = dict(zip('abcdef', list(range(6))))
    for key, val in A.items():
        print(key, val)