Thursday, July 5, 2018

Python Dictionaries


Introduction
------------

- another data type in Python
- consists of `key: value` pair inside `{}`
- sequences are indexed via element number (fruit[0]) while dictionaries are
  indexed via keys (telephone_number['John'])
- keys are immutable
- keys can be any of the following:
    a. strings
    b. numbers
    c. tuples (if contains only immutable object)
- you cannot use lists as keys because they can be modified using append(),
  insert(), etc..
- adding value on an existing key replaces the old value
- extracting a value from a non-existing key will result to `KeyError`

How to use dictionaries?
------------------------

Simple demo on how to use dictionaries
>>> tel = {'jack': 4098, 'sape': 4139}  # creating a dictionary
>>> tel['guido'] = 4127  # adds an entry
>>> tel
{'sape': 4139, 'guido': 4127, 'jack': 4098}
>>> tel['jack']
4098
>>> del tel['sape']  # deleting an entry
>>> tel['irv'] = 4127
>>> tel
{'guido': 4127, 'irv': 4127, 'jack': 4098}
>>> list(tel.keys())
['irv', 'guido', 'jack']
>>> sorted(tel.keys())
['guido', 'irv', 'jack']
>>> 'guido' in tel
True
>>> 'jack' not in tel
False
Creating an empty dictionary and adding
an entry
>>> empty = {}
>>> empty
{}
>>>
>>> empty['first entry'] = 1
>>> empty
{'first entry': 1}
>>>
Listing all keys of a dictionary
>>> tel.keys()
dict_keys(['jack', 'sape'])
>>>
Sorting keys
>>> sorted(dict.keys())
You can use dic() constructor to build a
dictionary directly from a sequence of
key-value pairs
>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'jack': 4098, 'guido': 4127}
>>>
>>> dict(sape=4139, guido=4127, jack=4098)  # alternative way, useful if keys are
{'sape': 4139, 'jack': 4098, 'guido': 4127} # simple strings
>>>
Creating a dict comprehension
>>> {x: x**2 for x in (2, 4, 6)}
{2: 4, 4: 16, 6: 36}
>>>
Other operations that can be done on
dictionaries
dict.clear()
dict.copy()
dict.fromkeys(seq[, value])
iter(dict)

Operations on dictionaries
--------------------------

Getting keys values
using get()
Format:
dict.get(KEY, VALUE)
 
Usage:
- a non-existent key returns None
- you may provide a value on non-existing keys


>>> dict = { 'name': 'john', 'tel': '123456' }
>>> dict.get('name')
'john'
>>> dict.get('occupation')
>>> print(dict.get('occupation'))
None
>>> print(dict.get('occupation', 'taxi driver'))
taxi driver
>>>
Merging
# How to merge two dictionaries
# in Python 3.5+

>>> x = {'a': 1, 'b': 2}
>>> y = {'b': 3, 'c': 4}
>>> z = {**x, **y}
>>> z
{'c': 4, 'a': 1, 'b': 3}

# In Python 2.x you could
# use this:
>>> z = dict(x, **y)
>>> z
{'a': 1, 'c': 4, 'b': 3}

# In these examples, Python merges dictionary keys
# in the order listed in the expression, overwriting
# duplicates from left to right.
#
Sorting
Use dict.items() to generate a list then feed that into
lambda.

>>> d
{'a': 500, 'b': 1000, 'c': 1}
>>>
>>>
>>> sorted(d.items(), key=lambda x: x[1])
[('c', 1), ('a', 500), ('b', 1000)]
>>>
>>> sorted(d.items(), key=lambda x: x[0])
[('a', 500), ('b', 1000), ('c', 1)]
>>>
>>>

Or you may use `operator` module.

>>> import operator
>>> sorted(d.items(), key=operator.itemgetter(1))
[('c', 1), ('a', 500), ('b', 1000)]
>>>
Ways of unpacking
Using a wrapper function:

 
>>> d
{'a': 1, 'b': 2, 'c': 3}
>>> def unpack_me(x, y, z):
...   print(x, y, z)
...
>>> unpack_me(*d)
a b c
>>>

Tutorials/Tips and Tricks
-------------------------

Emulating case statements
# Because Python has first-class functions they can
# be used to emulate switch/case statements

def dispatch_if(operator, x, y):
    if operator == 'add':
        return x + y
    elif operator == 'sub':
        return x - y
    elif operator == 'mul':
        return x * y
    elif operator == 'div':
        return x / y
    else:
        return None

def dispatch_dict(operator, x, y): --> I don't get this!!!
    return {
        'add': lambda: x + y,
        'sub': lambda: x - y,
        'mul': lambda: x * y,
        'div': lambda: x / y,
    }.get(operator, lambda: None)()


>>> dispatch_if('mul', 2, 8)
16

>>> dispatch_dict('mul', 2, 8)
16

>>> dispatch_if('unknown', 2, 8)
None

>>> dispatch_dict('unknown', 2, 8)
None

No comments:

Post a Comment