Dictionaries 4 - special classes

Download exercise zip

Browse online files

There are special classes we can use:

Class

Description

OrderedDict

Dictionary which allows to maintain the order of insertion of keys

Counter

Dictionary which allows to rapidly calculate histograms

What to do

  1. Unzip exercises zip in a folder, you should obtain something like this:

sets
    dictionaries1.ipynb
    dictionaries1-sol.ipynb
    dictionaries2.ipynb
    dictionaries2-sol.ipynb
    dictionaries3.ipynb
    dictionaries3-sol.ipynb
    dictionaries4.ipynb
    dictionaries4-sol.ipynb
    dictionaries5-chal.ipynb
    jupman.py

WARNING: to correctly visualize the notebook, it MUST be in an unzipped folder !

  1. open Jupyter Notebook from that folder. Two things should open, first a console and then a browser. The browser should show a file list: navigate the list and open the notebook dictionaries4.ipynb

  2. Go on reading the exercises file, sometimes you will find paragraphs marked Exercises which will ask to write Python commands in the following cells.

Shortcut keys:

  • to execute Python code inside a Jupyter cell, press Control + Enter

  • to execute Python code inside a Jupyter cell AND select next cell, press Shift + Enter

  • to execute Python code inside a Jupyter cell AND a create a new cell aftwerwards, press Alt + Enter

  • If the notebooks look stuck, try to select Kernel -> Restart

OrderedDict

As we said before, when we print a dictionary with print or we leave the visualization to Jupyter, most of the times couples are not in insertion order. For the order to be predictable, you must use an OrderedDict

First you need to import it from the collections module:

[2]:
from collections import OrderedDict
[3]:
od = OrderedDict()

An OrderedDict appears and behaves like regular dictionaries:

[4]:
od['some key'] = 5
od['some other key'] = 7
od[('an', 'immutable','tuple', 'as key')] = 3
od['Another key'] = 'now a string!'
od[123] = 'hello'

When visualizing with Jupyter, we see the insertion order:

[5]:
od
[5]:
OrderedDict([('some key', 5),
             ('some other key', 7),
             (('an', 'immutable', 'tuple', 'as key'), 3),
             ('Another key', 'now a string!'),
             (123, 'hello')])

As we see it with a regular print:

[6]:
print(od)
OrderedDict([('some key', 5), ('some other key', 7), (('an', 'immutable', 'tuple', 'as key'), 3), ('Another key', 'now a string!'), (123, 'hello')])

Let’s see how it appears in Python Tutor:

[7]:
from collections import OrderedDict
od = OrderedDict()
od['some key'] = 5
od['some other key'] = 7
od[('an', 'immutable','tuple', 'as key')] = 3
od['Another key'] = 'now a string!'
od[123] = 'hello'

jupman.pytut()
[7]:
Python Tutor visualization

Exercise - phonebook

Write some code which given three tuples with names and phone numbers, PRINTS an OrderedDict which associates names to phone numbers, in the order in which are proposed

  • Your code must work with any tuple

  • Do not forget to import OrderedDict from collections

Example:

t1 = ('Alice', '143242903')
t2 = ('Bob', '417483437')
t3 = ('Charles', '423413213')

after your code, it should result:

OrderedDict([('Alice', '143242903'), ('Bob', '417483437'), ('Charles', '423413213')])
Show solution
[8]:

t1 = ('Alice', '143242903') t2 = ('Bob', '417483437') t3 = ('Charles', '423413213') # write here

Exercise - OrderedDict copy

Given an OrderedDict od1 containing English to Italian translations, create a NEW OrderedDict called od2 which contains the same translations as input PLUS the translation 'water' : 'acqua'

  • NOTE 1: your code should work with any ordered dict as input

  • NOTE 2: od2 MUST be associated to a NEW OrderedDict !!

Example - given:

od1 = OrderedDict()
od1['dog'] = 'cane'
od1['home'] = 'casa'
od1['table'] = 'tavolo'

after your code, you should obtain:

>>> print(od1)
OrderedDict([('dog', 'cane'), ('home', 'casa'), ('table', 'tavolo')])
>>> print(od2)
OrderedDict([('dog', 'cane'), ('home', 'casa'), ('table', 'tavolo'), ('water', 'acqua')])
Show solution
[9]:

from collections import OrderedDict od1 = OrderedDict() od1['dog'] = 'cane' od1['home'] = 'casa' od1['table'] = 'tavolo' # write here

Counter

If we need to know how many different elements there are in a sequence (in other words, if we need to calculate a frequence histogram), the class Counter from collections module comes useful. Counter is a special type of dictionary, and first of all, we must declare to Python our intention to use it:

[10]:
from collections import Counter

Suppose we want to count how many different characters there are in this list:

[11]:
my_seq = ['t', 'e', 'm', 'p', 'e', 'r', 'a', 'm', 'e', 'n', 't']

We can initialize Counter like this:

[12]:
histogram = Counter(my_seq)

If we print it, we see that the first elements are the most frequent:

[13]:
print(histogram)
Counter({'e': 3, 't': 2, 'm': 2, 'p': 1, 'r': 1, 'a': 1, 'n': 1})

WARNING: IF WE DON’T USE print JUPYTER WILL PRINT IN ALPHABETICAL ORDER!

[14]:
histogram    # careful !
[14]:
Counter({'t': 2, 'e': 3, 'm': 2, 'p': 1, 'r': 1, 'a': 1, 'n': 1})

We can obtain a list with the n most frequent items by using the method most_common, which returns a list of tuples:

[15]:
histogram.most_common(5)
[15]:
[('e', 3), ('t', 2), ('m', 2), ('p', 1), ('r', 1)]

Counter can be initialized with any sequence, for example with tuples:

[16]:
ct = Counter((50,70,40,60,40,50,40,70,50,50,50,60,50,30,50,30,40,50,60,70))
print(ct)
Counter({50: 8, 40: 4, 70: 3, 60: 3, 30: 2})

or strings:

[17]:
cs = Counter('condonation')
[18]:
print(cs)
Counter({'o': 3, 'n': 3, 'c': 1, 'd': 1, 'a': 1, 't': 1, 'i': 1})

For other methods we refer to Python documentation

Exercise - saddened

Given a string s, write some code which prints:

  • the most frequent character

  • the least frequent character

  • how many and which different frequencies there are

  • Your code must work with any string s

  • Ignore the possibility there could be ties among the most/least frequent items

  • remember to import Counter from collections

Example - given:

s = 'saddened'

your code must print:

Among the most frequent ones we find ('d', 3)
Among the least frequent ones we find ('a', 1)
There are 3 different frequencies: {1, 2, 3}
Show solution
[19]:

s = 'saddened' # write here

Continue

Go on with first challenges

[ ]: