Python Tutorial_ Dictionaries
Python Tutorial_ Dictionaries
Home Python 2 Tutorial Python 3 Tutorial Advanced Topics Numerical Programming Machine Learning Tkinter Tutorial Contact
Dictionaries
If we try to find out the capital of Switzerland in the previous example, we raise a KeyError. To prevent these errors, there is an elegant way. The method pop() has an optional second parameter, which can be used
as a default value:
Python Training
Courses in Toronto, popitem
Canada
On site trainings in popitem() is a method of dict, which doesn't take any parameter and removes and returns an arbitrary (key,value) pair as a 2-tuple. If popitem() is applied on an empty dictionary, a KeyError will be raised.
Europe, Canada and
>>> capitals = {"Springfield":"Illinois", "Augusta":"Maine", "Boston": "Massachusetts", "Lansing":"Michigan", "Albany":"New York", "Olympia":"Washington", "Toronto":"Ontario"}
the US. >>> (city, state) = capitals.popitem()
>>> (city, state)
('Olympia', 'Washington')
>>> print(capitals.popitem())
('Albany', 'New York')
>>> print(capitals.popitem())
('Boston', 'Massachusetts')
>>> print(capitals.popitem())
('Lansing', 'Michigan')
>>> print(capitals.popitem())
('Toronto', 'Ontario')
>>>
If you try to access a key which doesn't exist, you will get an error message:
Another method to access the values via the key consists in using the get() method. get() is not raising an error, if an index doesn't exist. In this case it will return None. It's also possible to set a default value,
which will be returned, if an index doesn't exit:
Important Methods
>>> w = words.copy()
>>> words["cat"]="chat"
>>> print(w)
{'house': 'Haus', 'cat': 'Katze'}
>>> print(words)
{'house': 'Haus', 'cat': 'chat'}
This copy is a shallow and not a deep copy. If a value is a complex data type like a list, for example, in-place changes in this object have effects on the copy as well:
trainings2 = trainings.copy()
If we check the output, we can see that the title of course2 has been changed not only in the dictionary training but in trainings2 as well:
{'course2': {'trainer': 'Ella M. Charming', 'name': 'Perl Training Course for Beginners', 'location': 'Berlin'}, 'course3': {'trainer': 'Monica A. Snowdon', 'name': 'Python Text
Processing Course', 'location': 'München'}, 'course1': {'trainer': 'Steve G. Snake', 'name': 'Python Training Course for Beginners', 'location': 'Frankfurt'}}
Everything works the way you expect it, if you assign a new value, i.e. a new object, to a key:
trainings2 = trainings.copy()
If we want to understand the reason for this behaviour, we recommend our chapter "Shallow and Deep Copy".
The content of a dictionary can be cleared with the method clear(). The dictionary is not deleted, but set to an empty dictionary:
>>> w.clear()
>>> print(w)
{}
What about concatenating dictionaries, like we did with lists? There is someting similar for dictionaries: the update method
update() merges the keys and values of one dictionary into another, overwriting values of the same key:
But it's possible to use the method keys(), but we will get the same result:
The method values() is a convenient way for iterating directly over the values:
for key in d:
print(d[key])
If you are familiar with the timeit possibility of ipython, you can measure the time used for the two alternatives:
In [7]:
If you have worked for a while with Python, nearly inevitably the moment will come, when you want or have to convert lists into dictionaries or vice versa. It wouldn't be too
hard to write a function doing this. But Python wouldn't be Python, if it didn't provide such functionalities.
If we have a dictionary
The list L and the dictionary D contain the same content, i.e. the information content, or to express ot sententiously "The entropy of L and D is the same". Of course, the
information is harder to retrieve from the list L than from the dictionary D. To find a certain key in L, we would have to browse through the tuples of the list and compare
the first components of the tuples with the key we are looking for. This search is implicitly and extremely efficiently implemented for dictionaries.
It's possible to create lists from dictionaries by using the methods items(), keys() and values(). As the name implies the method keys() creates a list, which consists solely of the keys of the dictionary. values()
produces a list consisting of the values. items() can be used to create a list consisting of 2-tuples of (key,value)-pairs:
If we apply the method items() to a dictionary, we don't get a list back, as it used to be the case in Python 2, but a so-called items view. The items view can be turned into a list by applying the list function. We
have no information loss by turning a dictionary into an item view or an items list, i.e. it is possible to recreate the original dictionary from the view created by items(). Even though this list of 2-tuples has the same
entropy, i.e. the information content is the same, the efficiency of both approaches is completely different. The dictionary data type provides highly efficient methods to access, delete and change elements of the
dictionary, while in the case of lists these functions have to be implemented by the programmer.
Now we will turn our attention to the art of cooking, but don't be afraid, this remains a python course and not a cooking course. We want to show you, how to turn lists into dictionaries, if these lists satisfy certain
conditions.
We have two lists, one containing the dishes and the other one the corresponding countries:
Now we will create a dictionary, which assigns a dish, a country-specific dish, to a country; please forgive us for resorting to the common prejudices. For this purpose we need the function zip(). The name zip was
well chosen, because the two lists get combined like a zipper. The result is a list iterator. This means that we have to wrap a list() casting function around the zip call to get a list so that we can see what is going on:
Now our country-specific dishes are in a list form, - i.e. a list of two-tuples, where the first components are seen as keys and the second components as values - which can be automatically turned into a dictionary
by casting it with dict().
Yet, this is very inefficient, because we created a list of 2-tuples to turn this list into a dict. This can be done directly by applying dict to zip:
There is still one question concerning the function zip(). What happens, if one of the two argument lists contains more elements than the other one?
It's easy to answer: The superfluous elements, which cannot be paired, will be ignored:
So in this course, we will not answer the burning question, what the national dish of Switzerland is.
>>> country_specialities_dict = dict(list(zip(["pizza", "sauerkraut", "paella", "hamburger"], ["Italy", "Germany", "Spain", "USA"," Switzerland"])))
>>> print(country_specialities_dict)
{'paella': 'Spain', 'hamburger': 'USA', 'sauerkraut': 'Germany', 'pizza': 'Italy'}
>>>
On the other hand, the code in the previous script is gilding the lily:
Danger Lurking
Especialy for those migrating from Python 2.x to Python 3.x: zip() used to return a list, now it's returning an iterator. You have to keep in mind that iterators exhaust themselves, if they are used. You can see this in
the following interactive session:
>>> l1 = ["a","b","c"]
>>> l2 = [1,2,3]
>>> c = zip(l1, l2)
>>> for i in c:
... print(i)
...
('a', 1)
('b', 2)
('c', 3)
>>> for i in c:
... print(i)
...
This effect can be seen by calling the list casting operator as well:
>>> l1 = ["a","b","c"]
>>> l2 = [1,2,3]
>>> c = zip(l1,l2)
>>> z1 = list(c)
>>> z2 = list(c)
>>> print(z1)
[('a', 1), ('b', 2), ('c', 3)]
>>> print(z2)
[]
If you start this script, you will see that the dictionary you want to create will be empty:
$ python3 tricky_code.py
[('pizza', 'Italy'), ('sauerkraut', 'Germany'), ('paella', 'Spain'), ('hamburger', 'USA')]
{}
$
© 2011 - 2018, Bernd Klein, Bodenseo; Design by Denise Mitchinson adapted for python-course.eu by Bernd Klein