Objectives:
Upon completion of this lesson, you should be able to:
Describe the characteristics of the dict
in Python
Perform basic operations with dict
s including creation, "querying", updates, and traversing
Get an idea in which situations dict
s are and should be used
In Python, a dictionary (or dict
) is mapping between a set of
indices (keys) and a set of values
The items in a dictionary are key-value pairs
Keys can be any Python data type BUT
Because keys are used for indexing, they should be immutable
Values can be any Python data type
Values can be mutable or immutable
# Create an empty dictionary
eng2sp = dict()
eng2sp = {} # equivalent
print eng2sp
eng2sp['one'] = 'uno'
print eng2sp
eng2sp['two'] = 'dos'
print eng2sp
In general, the order of items in a dictionary is unpredictable
eng2sp = {'one': 'uno', 'two': 'dos', 'three': 'tres'}
print eng2sp
so never rely on any order of keys in the dictionary.
Note
If you need to maintain the order in which elements were added to dictionary, use "OrderedDict" (see
https://docs.python.org/2/library/collections.html#collections.OrderedDict)
Excercise
Try to create a dictionary with a key being
Which ones would work, and which ones would fail? What is the message?
You can create a dict from an iterable (e.g. list) which provides (key, value)
pairs:
eng2sp = dict([('one', 'uno'), ('two', 'dos'), ('three', 'tres')])
print eng2sp
Excercise
Quite frequently you might have already such two lists which contain your keys and values. Then you could easily create a necessary list of pairs from them up to produce a dictionary -- which function will you use? Do it:
eng = ['one', 'two', 'three']
sp = ['uno', 'dos', 'tres']
dict(TODO)
Similarly to list comprehensions, there are dict-comprehensions which allow for faster, flexible, and concise in code dynamic creation of lists. E.g. if we wanted a dictionary only for those english words with 'e' in them:
{e:s for e,s in zip(eng, sp) if 'e' in e}
eng2sp['three']
eng2sp['five']
if 'five' in eng2sp:
print eng2sp['five']
or use .get method and provide alternative default:
print eng2sp.get('five', "sorry -- no spanish")
Note that the in operator works a little bit differently for dictionaries than for other sequences
For offset indexed sequences (strings, lists, tuples), x in y checks to see whether x is an item in the sequence
6 in [4,5,6,7]
True
'two' in {'one':'uno', 'two':'dos', 'three':'tres'}
'dos' in {'one':'uno', 'two':'dos', 'three':'tres'}
# Let's add some new value
eng2sp['five'] = 'cinco'
print eng2sp
del eng2sp['five']
print eng2sp
Or, if you are interested to obtain the value and remove it from the dictionary -- use .pop
:
eng2sp['five'] = 'cinco'
five_sp = eng2sp.pop('five')
print five_sp
print eng2sp
The keys method returns a list of the keys in a dictionary
print eng2sp.keys()
The values method returns a list of the values
print eng2sp.values()
The items method returns a list of tuple pairs of the key-value pairs in a dictionary
print eng2sp.items()
value
s:'dos' in {'one':'uno', 'two':'dos', 'three':'tres'}.values()
Let's imagine we need to count appearances of every unique element of a sequence, e.g. of a string:
def histogram(seq):
d = dict()
for element in seq:
if element not in d:
d[element] = 1
else:
d[element] += 1
return d
h = histogram('brontosaurus')
print h
And lets create a helper function to print such a histogram:
def print_hist(hist):
for key in hist:
print key, hist[key]
h = histogram('brontosaurus')
print_hist(h)
Now that we have learned so much, let's change the print_hist function to use (key,value) pairs:
def print_hist(hist):
for key, value in hist:
print key, value
h = histogram('brontosaurus')
print_hist(h)
Question: What happened?
Excercises:
histogram
to make use of dict.get
and make implementation simpler/more concisedict
s do not preserve the order of items? So what if we wanted to get the histogram in order?def print_hist(hist):
for key in sorted(hist.keys()):
print key, hist[key]
h = histogram('brontosaurus')
print_hist(h)
MiniExcercise
Use above example code, but adjust it to make use of a .sort()
method of a list you obtain from hist.keys()
instead of using sorted
function
Excercise
Develop a function invert_dict
which for a dictionary would invert keys and values, i.e. would create inverse mapping. Here is a code "stub" and test cases:
def invert_dict(d):
# TODO magic, try to come up with 1 line solution
sp2eng = invert_dict(eng2sp)
assert(sp2eng == {'dos': 'two', 'tres': 'three', 'uno': 'one'})
Similarly to as tuple can absorb all positional arguments to a function (*args
), dict
can absorb all keyword arguments:
A parameter name that begins with ** gathers all the arguments into a dictionary
This allows functions to take a variable number of keyword arguments
You might frequently see a pattern such as
# some function, this one is just for example
def func(x, param=0):
print "got x=%s param=%s" % (x, param)
# another function which passes majority or all arguments
# into func
def func2(a, *args, **kwargs):
print a, args, kwargs
func(*args, **kwargs)
func2(1, 'three')
func2(1, 'four', param="123")
Question
What disadvantage(s) of such a construct?