Dictionaries 3 - Methods
Download exercise zip
In this notebook we will se the main ethods to extract data and manipulate dictionaries.
Methods:
Method |
Return |
Description |
---|---|---|
|
Return a view of keys which are present in the dictionary |
|
|
Return a view of values which are present in the dictionary |
|
|
Return a view of (key/value) couples present in the dictionary |
|
|
MODIFY the dictionary
|
What to do
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 !
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
dictionaries3.ipynb
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
keys
method
By calling the method .keys()
we can obtain the dictionary keys:
[2]:
vegetables = {'carrots' : 5,
'tomatoes' : 8,
'cabbage' : 3}
[3]:
vegetables.keys()
[3]:
dict_keys(['carrots', 'tomatoes', 'cabbage'])
WARNING: THE RETURNED SEQUENCE IS OF TYPE dict_keys
dict_keys
might look like a list but it is well different!
In particular, the returned sequence dict_keys
is a view on the original dictionary. In computer science, when we talk about views we typically intend collections which contain a part of the objects contained in another collection, and if the original collection gets modified, so is the view at the same time.
Let’s see what this means. First let’s assign the sequence of keys to a variable:
[4]:
ks = vegetables.keys()
Then we modify the original dictionary, adding an association:
[5]:
vegetables['potatoes'] = 8
If we now print ks
, we should see the change:
[6]:
ks
[6]:
dict_keys(['carrots', 'tomatoes', 'cabbage', 'potatoes'])
Sequence returned by .keys()
can change over time!
When reusing the sequence from .keys()
, ask yourself if the dictionary could have changed in the meanwhile
If we want a stable version as a sort of static ‘picture’ of dictionary keys at a given moment in time, we must explicitly convert them to another sequence, like for example a list
:
[7]:
as_list = list(vegetables.keys())
[8]:
as_list
[8]:
['carrots', 'tomatoes', 'cabbage', 'potatoes']
[9]:
vegetables['cocumber'] = 9
[10]:
as_list # no cocumbers
[10]:
['carrots', 'tomatoes', 'cabbage', 'potatoes']
Let’s see again the example in Python Tutor:
[11]:
# WARNING: FOR PYTHON TUTOR TO WORK, REMEMBER TO EXECUTE THIS CELL with Shift+Enter
# (it's sufficient to execute it only once)
import jupman
[12]:
vegetables = {'carrots' : 5,
'tomatoes' : 8,
'cabbage' : 3}
keys = vegetables.keys()
vegetables['potatoes'] = 8
as_list = list(vegetables.keys())
vegetables['cocumbers'] = 9
#print(as_list)
jupman.pytut()
[12]:
WARNING: WE CAN’T USE INDEXES WITH dict_keys
If we try, we will obtain an error:
>>> vegetables = {'carrots' : 5,
'tomatoes' : 8,
'cabbage' : 3}
>>> ks = vegetables.keys()
>>> ks[0]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-90-c888bf602918> in <module>()
----> 1 keys[0]
TypeError: 'dict_keys' object does not support indexing
WARNING: WE CANNOT DIRECTLY MODIFY dict_keys
There aren’t operations nor methods which allow us to change the elements of dict_keys
, you can only act on the original dictionary.
QUESTION: Look at the following code fragments, and for each try guessing if it can work (or if it gives an error):
diz = {'a':4, 'b':5} ks = diz.keys() ks.append('c')
diz = {'a':4, 'b':5} ks = diz.keys() ks.add('c')
diz = {'a':4, 'b':5} ks = diz.keys() ks['c'] = 3
QUESTION: Look at the following code fragments, and for each try guessing which result it produces (or if it gives an error):
diz = {'a':1,'b':2} s = set(diz.keys()) s.add(('c',3)) print(diz) print(s)
diz = {'a':3,'b':4} k = diz.keys() diz['c'] = 5 print(len(k))
diz = {'a':'x', 'b':'y'} print('a' in diz.keys())
diz1 = {'a':1,'b':2} chiavi = diz1.keys() diz2 = dict(diz1) diz2['c'] = 3 print('diz1=',diz1) print('diz2=',diz2) print('chiavi=',chiavi)
diz1 = {'a':'b','c':'d'} diz2 = {'a':'b','b':'c'} print( set(diz1.keys()) - set(diz2.keys()) )
diz1 = {'a':'b','c':'d'} diz2 = {'e':'a','f':'c'} ks = diz1.keys() del diz1[diz2['e']] del diz1[diz2['f']] print(len(ks))
Exercise - messy keys
✪ PRINT a LIST with all the keys in the dictionary
NOTE 1: it is NOT necessary for the list to be sorted
NOTE 2: to convert any sequence to a list, use the predefined function
list
[13]:
d = {'c':6, 'b':2,'a':5}
# write here
Exercise - sorted keys
✪ PRINT a LIST with all the dictionary keys
NOTE 1: Now it IS necessary for the list to be sorted
NOTE 2: to convert any sequence to a list, use the predefined function
list
[14]:
d = {'c':6, 'b':2,'a':5}
# write here
Exercise - keyring
Given the dictionaries d1
and d2
, write some code which puts into a list ks
all the keys in the two dictionaries, without duplicates and alphabetically sorted, and finally prints the list.
your code must work with any
d1
andd2
Example - given:
d1 = {
'a':5,
'b':9,
'e':2,
}
d2 = {'a':9,
'c':2,
'e':2,
'f':6}
after your code, it must result:
>>> print(keys)
['a', 'b', 'c', 'e', 'f']
[15]:
d1 = {
'a':5,
'b':9,
'e':2,
}
d2 = {'a':9,
'c':2,
'e':2,
'f':6}
# write here
values
method
Given a dictionary, we can obtain all the values by calling the method .values()
Imagine we have a dictionary vehicles
which assigns an owner to each car plate:
[16]:
vehicles = {
'AA111AA' : 'Mario',
'BB222BB' : 'Lidia',
'CC333CC' : 'Mario',
'DD444DD' : 'Gino',
'EE555EE' : 'Gino'
}
owners = vehicles.values()
WARNING: THE RETURNED SEQUENCE IS OF TYPE dict_values
dict_values
may seem a list but it’s not!
We’ve seen dict_keys
is a view on the original dictionary, and so is dict_values
, thus by adding an association to vehicles
…
[17]:
vehicles['FF666FF'] = 'Paola'
… the view owners
will automatically result changed:
[18]:
owners
[18]:
dict_values(['Mario', 'Lidia', 'Mario', 'Gino', 'Gino', 'Paola'])
We also note that being values of a dictionary, duplicates are allowed.
WARNING: WE CANNOT USE INDEXES WITH dict_values
If we try, we will get an error:
>>> owners[0]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-90-c888bf602918> in <module>()
----> 1 owners[0]
TypeError: 'dict_values' object does not support indexing
WARNING: WE CANNOT DIRECTLY MODIFY dict_values
There aren’t operations nor methods that allow us to change the elements of dict_values
, we can only act on the original dictionary.
QUESTION: Look at the following code fragments, and for each try guessing the result it produces (or if it gives an error):
diz = {'a':4, 'b':5} vals = diz.values() vals.append(4)
d = {0:'a', 1:'b', 2:'b'} vals = d.values() d[2]='c' print(vals)
diz = {'a':4, 'b':5} vals = diz.values() vals.add(5)
diz = {0:1, 1:2, 2:3} diz[list(diz.values())[0]-1]
diz = {'a':4, 'b':5} vals = diz.values() vals['c'] = 6
diz = {'a':4, 'b':5} vals = diz.values() vals[6] = 'c'
Exercise - one by one
Given a dictionary my_dict
, write some code which prints True
if each key is associated to a value different from the values of all other keys. Otherwise prints False
.
Example 1 - given:
my_dict = {'a' : 3,
'c' : 6,
'g' : 8}
After your code, it must print True
(because 3
,6
and 8
are all different)
True
Example 2 - given:
my_dict = {'x' : 5,
'y' : 7,
'z' : 5}
it must print:
False
[19]:
my_dict = {'a' : 3,
'c' : 6,
'g' : 8}
"""
my_dict= {'x' : 5,
'y' : 7,
'z' : 5}
"""
# write here
Exercise - bag
Given a dictionary my_dict
of character associations, write some code which puts into the variable bag
the sorted list of all the keys and values.
Example - given:
my_dict = {
'a':'b',
'b':'f',
'c':'b',
'd':'e'
}
After your code, it must print:
>>> print(bag)
['a', 'b', 'c', 'd', 'e', 'f']
[20]:
my_dict = {
'a':'b',
'b':'f',
'c':'b',
'd':'e'
}
# write here
Exercise - common values
Given two dictionaries d1
and d2
, write some code which PRINTS True
if they have at least a value in common (without considering the keys)
Example 1 - given:
d1 = {
'a':4,
'k':2,
'm':5
}
d2 = {
'b':2,
'e':4,
'g':9,
'h':1
}
after your code, it must print True
(because they have the values 2
and 4
in common):
Common values? True
Example 2 - given:
d1 = {
'd':1,
'e':2,
'f':6
}
d2 = {
'a':3,
'b':5,
'c':9,
'd':7
}
after your code, it must print:
Common values? False
[21]:
d1 = {
'a':4,
'k':2,
'm':5
}
d2 = {
'b':2,
'e':4,
'g':9,
'h':1
}
"""
d1 = {
'd':1,
'e':2,
'f':6
}
d2 = {
'a':3,
'b':5,
'c':9,
'd':7
}
"""
# write here
Exercise - small big
Given a dictionary d
which has integers as keys and values, print True
if the smaller key is equal to the greatest value.
Example 1 - given:
d = {
14:1,
11:7,
7:3,
70:5
}
after your code, it must print True
(because the smallest key is 7
which is equal to the greates value 7
):
True
Example 2 - given:
d = {
12:1,
11:9,
7:3,
2:5,
9:1
}
after your code, it must print False
(because the smallest key 2
is different from the greatest value9
):
False
[22]:
d = {
14:1,
11:7,
7:3,
70:5
}
"""
d = {
12:1,
11:9,
7:3,
2:5,
9:1
}
"""
# write here
items
method
We can extract all the key/value associations as a list of couples of type tuple with the method .items()
. Let’s see an example which associates attractions to the city they are in:
[23]:
holiday = {'Piazza S.Marco' :'Venezia',
'Fontana di Trevi':'Roma',
'Uffizi' :'Firenze',
'Colosseo' :'Roma',
}
[24]:
holiday.items()
[24]:
dict_items([('Piazza S.Marco', 'Venezia'), ('Fontana di Trevi', 'Roma'), ('Uffizi', 'Firenze'), ('Colosseo', 'Roma')])
In this case we see that an object of type dict_items
is returned. As in previous cases, it is a view which we can’t directly modify. If the original dictionary gets changed, the mutation will be reflected in the view:
[25]:
attractions = holiday.items()
[26]:
holiday['Palazzo Ducale'] = 'Venezia'
[27]:
attractions
[27]:
dict_items([('Piazza S.Marco', 'Venezia'), ('Fontana di Trevi', 'Roma'), ('Uffizi', 'Firenze'), ('Colosseo', 'Roma'), ('Palazzo Ducale', 'Venezia')])
QUESTION: Look at the following code fragments, and for each try guessing which result it produces (or if it gives an error):
{'a':7, 'b':9}.items()[0] = ('c',8)
dict({'a':7,'b':5}.items())['a']
len(set({'a':'b', 'a':'B'}.items()))
{'a':2}.items().find(('a',2))
{'a':2}.items().index(('a',2))
list({'a':2}.items()).index(('a',2))
diz1 = {'a':7, 'b':5} diz2 = dict(diz1.items()) diz1['a'] = 6 print(diz1 == diz2)
('a','b') in {'a':('a','b'), 'b':('a','b')}.items()
('a','b') in list({'a':('a','b'), 'b':('a','b')}.items())[0]
Exercise - union without update
Given the dictionaries d1
and d2
, write some code which creates a NEW dictionary d3
containing all the key/value couples from d1
and d2
.
we suppose all the key/value couples are distinct
DO NOT use cycles
DO NOT use
.update()
your code must work for any
d1
andd2
Example - given:
d1 = {'a':4,
'b':7}
d2 = {'c':5,
'd':8,
'e':2}
after your code, it must result (order is not important):
>>> print(d3)
{'a': 4, 'e': 2, 'd': 8, 'c': 5, 'b': 7}
[28]:
d1 = {'a':4,
'b':7}
d2 = {'c':5,
'd':8,
'e':2}
# write here
update
method
Having a dictionary to start with, it is possibly to MODIFY it by joining another with the method .update()
:
[29]:
d1 = {'goats' :6,
'cabbage' :9,
'shepherds':1}
d2 = {'goats' :12,
'cabbage':15,
'benches':3,
'hay' :7}
[30]:
d1.update(d2)
[31]:
d1
[31]:
{'goats': 12, 'cabbage': 15, 'shepherds': 1, 'benches': 3, 'hay': 7}
Note how the common keys among the two dictionaries like 'goats'
and 'cabbage'
have values from the second.
If we will, it’s also possible to pass a sequence of couples like this:
[32]:
d1.update([('hay',3),('benches',18), ('barns',4)])
[33]:
d1
[33]:
{'goats': 12,
'cabbage': 15,
'shepherds': 1,
'benches': 18,
'hay': 3,
'barns': 4}
Exercise - axby
Given a dictionary dcc
which associates characters to characters and a string s
formatted with couples of characters like ax
separated by a semi-colon ;
, substitute all the values in dcc
with the corresponding values denoted in the string.
your code must work for any dictionary
my_dict
and lists
Example - given:
dcc = {
'a':'x',
'b':'y',
'c':'z',
'd':'w'
}
s = 'bx;cw;ex'
after your code, it must result:
>>> dcc
{'a': 'x', 'b': 'x', 'c': 'w', 'd': 'w', 'e': 'x'}
[34]:
dcc = {
'a':'x',
'b':'y',
'c':'z',
'd':'w'
}
s = 'bx;cw;ex'
# write here
Continue
Go on with Dictionaries 4