13. Dictionary

What is Dictionary

The compound data types (strings, lists, and tuples) are sequential collections. This means that the items in the collection are ordered from left to right and they use integers as indices to access the values they contain.

Dictionaries are a different kind of collection. They are Python’s built-in mapping type. A map is an unordered, associative collection. The association, or mapping, is from a key, which can be any immutable type, to a value, which can be any Python data object.

Create a dictionary

One way to create a dictionary is to start with the empty dictionary and add key:value pairs. The empty dictionary is denoted {}

In [1]:
eng2sp = {}
eng2sp["one"] = "uno"
eng2sp["two"] = "dos"
eng2sp["three"] = "tres"
print(eng2sp)
{'one': 'uno', 'two': 'dos', 'three': 'tres'}
In [2]:
from IPython.display import IFrame
IFrame("http://pythontutor.com/iframe-embed.html#code=eng2sp%20%3D%20%7B%7D%0Aeng2sp%5B%22one%22%5D%20%3D%20%22uno%22%0Aeng2sp%5B%22two%22%5D%20%3D%20%22dos%22%0Aeng2sp%5B%22three%22%5D%20%3D%20%22tres%22&codeDivHeight=400&codeDivWidth=350&cumulative=false&curInstr=0&heapPrimitives=false&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false", width='100%', height=450)
Out[2]:
In [3]:
eng2sp = {'three': 'tres', 'one': 'uno', 'two': 'dos'}
value = eng2sp['two']
print(value)
dos

why we use dictionaries instead of a list of tuples

Think about finding a value associated with a key:

In [4]:
d = {"apples": 430, "bananas": 312, 
     "oranges": 525, "pears": 217}

l = [('apples', 430), ('bananas', 312),
     ('oranges', 525), ('pears', 217)]

The reason is dictionaries are very fast, implemented using a technique called hashing, which allows us to access a value very quickly.

By contrast, the list of tuples implementation is slow.

Exercise

1. A dictionary is an unordered collection of key-value pairs.
(A) False
(B) True
2. What is printed by the following statements?
mydict = {"cat":12, "dog":6, "elephant":23}
print(mydict["dog"])
(A) 12
(B) 6
(C) 23
(D) Error, you cannot use the index operator with a dictionary.

Keys must be hashable objects

An object is hashable if:

  1. It supports the hash() function via a hash() method that always returns the same value over the lifetime of the object.
  2. It supports equality via an eq() method.
  3. If a == b is True then hash(a) == hash(b) must also be True.
In [6]:
#Hashable types: str, bytes, int, float, frozenset
t1 = (1,2,(30,40))
print(hash(t1))

t2 = (1,2,[30,40])
print(hash(t2))

t3 = (1,2,frozenset([30,40]))
print(hash(t3))

t2 = (1,2,[30,40])
t2[2] += [5]
8027212646858338501
8027212646858338501
985328935373711578
In [7]:
a = dict(one=1, two=2)
b = {'one':1, 'two':2}
c = dict(zip(['one','two'],[1,2]))
d = dict([('two',2),('one',1)])
e = dict({'two':2, 'one':1})
a == b == c == d == e
Out[7]:
True

dict Comprehensions

In [8]:
DIAL_CODES = [
    (86, 'China'),
    (91, 'India'),
    (1, 'United States'),
    (7, 'Russia'),
    (81, 'Japan'),
    (55, 'Brazil'),
    (234, 'Nigeria')
]
In [9]:
country_codes = {country:code for code, country in DIAL_CODES}
print(country_codes)
{'China': 86, 'India': 91, 'United States': 1, 'Russia': 7, 'Japan': 81, 'Brazil': 55, 'Nigeria': 234}
In [10]:
{code:country.upper() for country, code in country_codes.items() if code < 66}
Out[10]:
{1: 'UNITED STATES', 7: 'RUSSIA', 55: 'BRAZIL'}

Dictionary Operations

In [11]:
inventory = {"apples": 430, "bananas": 312, "oranges": 525, "pears": 217}

del inventory["oranges"]

print(inventory)
{'apples': 430, 'bananas': 312, 'pears': 217}
In [12]:
inventory["pears"] = 0
print(inventory)
{'apples': 430, 'bananas': 312, 'pears': 0}
In [13]:
inventory["oranges"] = 0

print(len(inventory))
print(inventory)
4
{'apples': 430, 'bananas': 312, 'pears': 0, 'oranges': 0}

Exercise

What is printed by the following statements?
mydict = {"cat":12, "dog":6, "elephant":23}
mydict["mouse"] = mydict["cat"] + mydict["dog"]
print(mydict["mouse"])
(A) 12
(B) 0
(C) 18
(D) Error, there is no entry with mouse as the key.

Dictionary methods

Method Parameters Description
keys none Returns a view of the keys in the dictionary
values none Returns a view of the values in the dictionary
items none Returns a view of the key-value pairs in the dictionary
get key Returns the value associated with key; None otherwise
get key,alt Returns the value associated with key; alt otherwise
In [14]:
for k in eng2sp.keys(): 
   print("Got key", k, "which maps to value", eng2sp[k])

print(type(eng2sp.keys()))
ks = list(eng2sp.keys())
print(ks)
Got key three which maps to value tres
Got key one which maps to value uno
Got key two which maps to value dos
<class 'dict_keys'>
['three', 'one', 'two']

It is so common to iterate over the keys in a dictionary that we can omit the keys method call in the for loop — iterating over a dictionary implicitly iterates over its keys:

In [15]:
for k in eng2sp:
   print("Got key", k)
Got key three
Got key one
Got key two

values() and items() method

In [16]:
print(list(eng2sp.values()))

print(list(eng2sp.items()))
['tres', 'uno', 'dos']
[('three', 'tres'), ('one', 'uno'), ('two', 'dos')]
In [17]:
for (k,v) in eng2sp.items():
    print("Got",k,"that maps to",v)
Got three that maps to tres
Got one that maps to uno
Got two that maps to dos

get()

In [18]:
inventory = {'apples': 430, 'bananas': 312, 'oranges': 525, 'pears': 217}

print(inventory.get("apples"))
print(inventory.get("cherries"))

print(inventory.get("cherries", 0))
430
None
0

in, not in

In [19]:
inventory = {'apples': 430, 'bananas': 312, 'oranges': 525, 'pears': 217}
print('apples' in inventory)
print('cherries' not in inventory)

if 'bananas' in inventory:
    print(inventory['bananas'])
else:
    print("We have no bananas")
True
True
312

Exercise

1. What is printed by the following statements?
mydict = {"cat":12, "dog":6, "elephant":23, "bear":20}
keylist = list(mydict.keys())
keylist.sort()
print(keylist[3])
(A) cat
(B) dog
(C) elephant
(D) bear
2. What is printed by the following statements?
mydict = {"cat":12, "dog":6, "elephant":23, "bear":20}
answer = mydict.get("cat") // mydict.get("dog")
print(answer)
(A) 2
(B) 0.5
(C) bear
(D) Error, divide is not a valid operation on dictionaries.

3. What is printed by the following statements?

mydict = {"cat":12, "dog":6, "elephant":23, "bear":20}
print("dog" in mydict)
(A) True
(B) False
4. What is printed by the following statements?
mydict = {"cat":12, "dog":6, "elephant":23, "bear":20}
print(23 in mydict)
(A) True
(B) False
5. What is printed by the following statements?
total = 0
mydict = {"cat":12, "dog":6, "elephant":23, "bear":20}
for akey in mydict:
   if len(akey) > 3:
      total = total + mydict[akey]
print(total)
(A) 18
(B) 43
(C) 0
(D) 61

Fibonacci numbers

In [21]:
alreadyknown = {0: 0, 1: 1}

def fib(n):
    if n not in alreadyknown:
        new_value = fib(n-1) + fib(n-2)
        alreadyknown[n] = new_value
    return alreadyknown[n]

fib(100)
Out[21]:
354224848179261915075
In [22]:
%%timeit 

fib(100)
100 ns ± 3.51 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

Counting letters

In [23]:
def countLetters(text):
    counts = {}

    for l in text:
        counts[l] = counts.get(l, 0) + 1
    
    return counts
In [24]:
t = 'Such a frequency table might be useful for compressing a text file.'

counts = countLetters(t)

print(counts)
{'S': 1, 'u': 4, 'c': 3, 'h': 2, ' ': 11, 'a': 3, 'f': 4, 'r': 3, 'e': 8, 'q': 1, 'n': 2, 'y': 1, 't': 4, 'b': 2, 'l': 3, 'm': 2, 'i': 3, 'g': 2, 's': 3, 'o': 2, 'p': 1, 'x': 1, '.': 1}
In [25]:
c_items = list(counts.items())
c_items.sort()
print(c_items)
[(' ', 11), ('.', 1), ('S', 1), ('a', 3), ('b', 2), ('c', 3), ('e', 8), ('f', 4), ('g', 2), ('h', 2), ('i', 3), ('l', 3), ('m', 2), ('n', 2), ('o', 2), ('p', 1), ('q', 1), ('r', 3), ('s', 3), ('t', 4), ('u', 4), ('x', 1), ('y', 1)]

Variations of dict

collections.OrderedDict

Ordered dictionaries are just like regular dictionaries but they remember the order that items were inserted. When iterating over an ordered dictionary, the items are returned in the order their keys were first added.

In [26]:
from collections import OrderedDict
# regular unsorted dictionary
d = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}

# dictionary sorted by key
print(OrderedDict(sorted(d.items(), key=lambda t: t[0])))

# dictionary sorted by value
print( OrderedDict(sorted(d.items(), key=lambda t: t[1])))

# dictionary sorted by length of the key string
print( OrderedDict(sorted(d.items(), key=lambda t: len(t[0]))))
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])
OrderedDict([('pear', 1), ('apple', 4), ('banana', 3), ('orange', 2)])

collections.ChainMap

A ChainMap groups multiple dicts or other mappings together to create a single, updateable view. If no maps are specified, a single empty dictionary is provided so that a new chain always has at least one mapping.

In [27]:
import builtins
from collections import ChainMap
pylookup = ChainMap(locals(), globals(), vars(builtins))
print(pylookup)
ChainMap({'__name__': '__main__', '__doc__': 'Automatically created module for IPython interactive environment', '__package__': None, '__loader__': None, '__spec__': None, '__builtin__': <module 'builtins' (built-in)>, '__builtins__': <module 'builtins' (built-in)>, '_ih': ['', 'eng2sp = {}\neng2sp["one"] = "uno"\neng2sp["two"] = "dos"\neng2sp["three"] = "tres"\nprint(eng2sp)', 'from IPython.display import IFrame\nIFrame("http://pythontutor.com/iframe-embed.html#code=eng2sp%20%3D%20%7B%7D%0Aeng2sp%5B%22one%22%5D%20%3D%20%22uno%22%0Aeng2sp%5B%22two%22%5D%20%3D%20%22dos%22%0Aeng2sp%5B%22three%22%5D%20%3D%20%22tres%22&codeDivHeight=400&codeDivWidth=350&cumulative=false&curInstr=0&heapPrimitives=false&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false", width=\'100%\', height=450)', "eng2sp = {'three': 'tres', 'one': 'uno', 'two': 'dos'}\nvalue = eng2sp['two']\nprint(value)", 'd = {"apples": 430, "bananas": 312, \n     "oranges": 525, "pears": 217}\n\nl = [(\'apples\', 430), (\'bananas\', 312),\n     (\'oranges\', 525), (\'pears\', 217)]', '#Hashable types: str, bytes, int, float, frozenset\nt1 = (1,2,(30,40))\nprint(hash(t1))\n\nt2 = (1,2,[30,40])\nprint(hash(t2))\n\nt3 = (1,2,frozenset([30,40]))\nprint(hash(t3))', '#Hashable types: str, bytes, int, float, frozenset\nt1 = (1,2,(30,40))\nprint(hash(t1))\n\nt2 = (1,2,(30,40))\nprint(hash(t2))\n\nt3 = (1,2,frozenset([30,40]))\nprint(hash(t3))', "a = dict(one=1, two=2)\nb = {'one':1, 'two':2}\nc = dict(zip(['one','two'],[1,2]))\nd = dict([('two',2),('one',1)])\ne = dict({'two':2, 'one':1})\na == b == c == d == e", "DIAL_CODES = [\n    (86, 'China'),\n    (91, 'India'),\n    (1, 'United States'),\n    (7, 'Russia'),\n    (81, 'Japan'),\n    (55, 'Brazil'),\n    (234, 'Nigeria')\n]", 'country_codes = {country:code for code, country in DIAL_CODES}\nprint(country_codes)', '{code:country.upper() for country, code in country_codes.items() if code < 66}', 'inventory = {"apples": 430, "bananas": 312, "oranges": 525, "pears": 217}\n\ndel inventory["oranges"]\n\nprint(inventory)', 'inventory["pears"] = 0\nprint(inventory)', 'inventory["oranges"] = 0\n\nprint(len(inventory))\nprint(inventory)', 'for k in eng2sp.keys(): \n   print("Got key", k, "which maps to value", eng2sp[k])\n\nprint(type(eng2sp.keys()))\nks = list(eng2sp.keys())\nprint(ks)', 'for k in eng2sp:\n   print("Got key", k)', 'print(list(eng2sp.values()))\n\nprint(list(eng2sp.items()))', 'for (k,v) in eng2sp.items():\n    print("Got",k,"that maps to",v)', 'inventory = {\'apples\': 430, \'bananas\': 312, \'oranges\': 525, \'pears\': 217}\n\nprint(inventory.get("apples"))\nprint(inventory.get("cherries"))\n\nprint(inventory.get("cherries", 0))', 'inventory = {\'apples\': 430, \'bananas\': 312, \'oranges\': 525, \'pears\': 217}\nprint(\'apples\' in inventory)\nprint(\'cherries\' not in inventory)\n\nif \'bananas\' in inventory:\n    print(inventory[\'bananas\'])\nelse:\n    print("We have no bananas")', 'alreadyknown = {0: 0, 1: 1}\n\ndef fib(n):\n    if n not in alreadyknown:\n        new_value = fib(n-1) + fib(n-2)\n        alreadyknown[n] = new_value\n    return alreadyknown[n]\n\nfib(35)', 'alreadyknown = {0: 0, 1: 1}\n\ndef fib(n):\n    if n not in alreadyknown:\n        new_value = fib(n-1) + fib(n-2)\n        alreadyknown[n] = new_value\n    return alreadyknown[n]\n\nfib(100)', "get_ipython().run_cell_magic('timeit', '', '\\nfib(100)\\n')", 'def countLetters(text):\n    counts = {}\n\n    for l in text:\n        counts[l] = counts.get(l, 0) + 1\n    \n    return counts', "t = 'Such a frequency table might be useful for compressing a text file.'\n\ncounts = countLetters(t)\n\nprint(counts)", 'c_items = list(counts.items())\nc_items.sort()\nprint(c_items)', "from collections import OrderedDict\n# regular unsorted dictionary\nd = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}\n\n# dictionary sorted by key\nprint(OrderedDict(sorted(d.items(), key=lambda t: t[0])))\n\n# dictionary sorted by value\nprint( OrderedDict(sorted(d.items(), key=lambda t: t[1])))\n\n# dictionary sorted by length of the key string\nprint( OrderedDict(sorted(d.items(), key=lambda t: len(t[0]))))", 'import builtins\nfrom collections import ChainMap\npylookup = ChainMap(locals(), globals(), vars(builtins))\nprint(pylookup)'], '_oh': {2: <IPython.lib.display.IFrame object at 0x7f98f8151400>, 7: True, 10: {1: 'UNITED STATES', 7: 'RUSSIA', 55: 'BRAZIL'}, 20: 9227465, 21: 354224848179261915075}, '_dh': ['/Users/caodg/Workspace/Course/Python/ic/notebooks'], 'In': ['', 'eng2sp = {}\neng2sp["one"] = "uno"\neng2sp["two"] = "dos"\neng2sp["three"] = "tres"\nprint(eng2sp)', 'from IPython.display import IFrame\nIFrame("http://pythontutor.com/iframe-embed.html#code=eng2sp%20%3D%20%7B%7D%0Aeng2sp%5B%22one%22%5D%20%3D%20%22uno%22%0Aeng2sp%5B%22two%22%5D%20%3D%20%22dos%22%0Aeng2sp%5B%22three%22%5D%20%3D%20%22tres%22&codeDivHeight=400&codeDivWidth=350&cumulative=false&curInstr=0&heapPrimitives=false&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false", width=\'100%\', height=450)', "eng2sp = {'three': 'tres', 'one': 'uno', 'two': 'dos'}\nvalue = eng2sp['two']\nprint(value)", 'd = {"apples": 430, "bananas": 312, \n     "oranges": 525, "pears": 217}\n\nl = [(\'apples\', 430), (\'bananas\', 312),\n     (\'oranges\', 525), (\'pears\', 217)]', '#Hashable types: str, bytes, int, float, frozenset\nt1 = (1,2,(30,40))\nprint(hash(t1))\n\nt2 = (1,2,[30,40])\nprint(hash(t2))\n\nt3 = (1,2,frozenset([30,40]))\nprint(hash(t3))', '#Hashable types: str, bytes, int, float, frozenset\nt1 = (1,2,(30,40))\nprint(hash(t1))\n\nt2 = (1,2,(30,40))\nprint(hash(t2))\n\nt3 = (1,2,frozenset([30,40]))\nprint(hash(t3))', "a = dict(one=1, two=2)\nb = {'one':1, 'two':2}\nc = dict(zip(['one','two'],[1,2]))\nd = dict([('two',2),('one',1)])\ne = dict({'two':2, 'one':1})\na == b == c == d == e", "DIAL_CODES = [\n    (86, 'China'),\n    (91, 'India'),\n    (1, 'United States'),\n    (7, 'Russia'),\n    (81, 'Japan'),\n    (55, 'Brazil'),\n    (234, 'Nigeria')\n]", 'country_codes = {country:code for code, country in DIAL_CODES}\nprint(country_codes)', '{code:country.upper() for country, code in country_codes.items() if code < 66}', 'inventory = {"apples": 430, "bananas": 312, "oranges": 525, "pears": 217}\n\ndel inventory["oranges"]\n\nprint(inventory)', 'inventory["pears"] = 0\nprint(inventory)', 'inventory["oranges"] = 0\n\nprint(len(inventory))\nprint(inventory)', 'for k in eng2sp.keys(): \n   print("Got key", k, "which maps to value", eng2sp[k])\n\nprint(type(eng2sp.keys()))\nks = list(eng2sp.keys())\nprint(ks)', 'for k in eng2sp:\n   print("Got key", k)', 'print(list(eng2sp.values()))\n\nprint(list(eng2sp.items()))', 'for (k,v) in eng2sp.items():\n    print("Got",k,"that maps to",v)', 'inventory = {\'apples\': 430, \'bananas\': 312, \'oranges\': 525, \'pears\': 217}\n\nprint(inventory.get("apples"))\nprint(inventory.get("cherries"))\n\nprint(inventory.get("cherries", 0))', 'inventory = {\'apples\': 430, \'bananas\': 312, \'oranges\': 525, \'pears\': 217}\nprint(\'apples\' in inventory)\nprint(\'cherries\' not in inventory)\n\nif \'bananas\' in inventory:\n    print(inventory[\'bananas\'])\nelse:\n    print("We have no bananas")', 'alreadyknown = {0: 0, 1: 1}\n\ndef fib(n):\n    if n not in alreadyknown:\n        new_value = fib(n-1) + fib(n-2)\n        alreadyknown[n] = new_value\n    return alreadyknown[n]\n\nfib(35)', 'alreadyknown = {0: 0, 1: 1}\n\ndef fib(n):\n    if n not in alreadyknown:\n        new_value = fib(n-1) + fib(n-2)\n        alreadyknown[n] = new_value\n    return alreadyknown[n]\n\nfib(100)', "get_ipython().run_cell_magic('timeit', '', '\\nfib(100)\\n')", 'def countLetters(text):\n    counts = {}\n\n    for l in text:\n        counts[l] = counts.get(l, 0) + 1\n    \n    return counts', "t = 'Such a frequency table might be useful for compressing a text file.'\n\ncounts = countLetters(t)\n\nprint(counts)", 'c_items = list(counts.items())\nc_items.sort()\nprint(c_items)', "from collections import OrderedDict\n# regular unsorted dictionary\nd = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}\n\n# dictionary sorted by key\nprint(OrderedDict(sorted(d.items(), key=lambda t: t[0])))\n\n# dictionary sorted by value\nprint( OrderedDict(sorted(d.items(), key=lambda t: t[1])))\n\n# dictionary sorted by length of the key string\nprint( OrderedDict(sorted(d.items(), key=lambda t: len(t[0]))))", 'import builtins\nfrom collections import ChainMap\npylookup = ChainMap(locals(), globals(), vars(builtins))\nprint(pylookup)'], 'Out': {2: <IPython.lib.display.IFrame object at 0x7f98f8151400>, 7: True, 10: {1: 'UNITED STATES', 7: 'RUSSIA', 55: 'BRAZIL'}, 20: 9227465, 21: 354224848179261915075}, 'get_ipython': <bound method InteractiveShell.get_ipython of <ipykernel.zmqshell.ZMQInteractiveShell object at 0x7f9918719b70>>, 'exit': <IPython.core.autocall.ZMQExitAutocall object at 0x7f98e84856a0>, 'quit': <IPython.core.autocall.ZMQExitAutocall object at 0x7f98e84856a0>, '_': 354224848179261915075, '__': 9227465, '___': {1: 'UNITED STATES', 7: 'RUSSIA', 55: 'BRAZIL'}, '_i': "from collections import OrderedDict\n# regular unsorted dictionary\nd = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}\n\n# dictionary sorted by key\nprint(OrderedDict(sorted(d.items(), key=lambda t: t[0])))\n\n# dictionary sorted by value\nprint( OrderedDict(sorted(d.items(), key=lambda t: t[1])))\n\n# dictionary sorted by length of the key string\nprint( OrderedDict(sorted(d.items(), key=lambda t: len(t[0]))))", '_ii': 'c_items = list(counts.items())\nc_items.sort()\nprint(c_items)', '_iii': "t = 'Such a frequency table might be useful for compressing a text file.'\n\ncounts = countLetters(t)\n\nprint(counts)", '_i1': 'eng2sp = {}\neng2sp["one"] = "uno"\neng2sp["two"] = "dos"\neng2sp["three"] = "tres"\nprint(eng2sp)', 'eng2sp': {'three': 'tres', 'one': 'uno', 'two': 'dos'}, '_i2': 'from IPython.display import IFrame\nIFrame("http://pythontutor.com/iframe-embed.html#code=eng2sp%20%3D%20%7B%7D%0Aeng2sp%5B%22one%22%5D%20%3D%20%22uno%22%0Aeng2sp%5B%22two%22%5D%20%3D%20%22dos%22%0Aeng2sp%5B%22three%22%5D%20%3D%20%22tres%22&codeDivHeight=400&codeDivWidth=350&cumulative=false&curInstr=0&heapPrimitives=false&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false", width=\'100%\', height=450)', 'IFrame': <class 'IPython.lib.display.IFrame'>, '_2': <IPython.lib.display.IFrame object at 0x7f98f8151400>, '_i3': "eng2sp = {'three': 'tres', 'one': 'uno', 'two': 'dos'}\nvalue = eng2sp['two']\nprint(value)", 'value': 'dos', '_i4': 'd = {"apples": 430, "bananas": 312, \n     "oranges": 525, "pears": 217}\n\nl = [(\'apples\', 430), (\'bananas\', 312),\n     (\'oranges\', 525), (\'pears\', 217)]', 'd': {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}, 'l': [('apples', 430), ('bananas', 312), ('oranges', 525), ('pears', 217)], '_i5': '#Hashable types: str, bytes, int, float, frozenset\nt1 = (1,2,(30,40))\nprint(hash(t1))\n\nt2 = (1,2,[30,40])\nprint(hash(t2))\n\nt3 = (1,2,frozenset([30,40]))\nprint(hash(t3))', 't1': (1, 2, (30, 40)), 't2': (1, 2, (30, 40)), '_i6': '#Hashable types: str, bytes, int, float, frozenset\nt1 = (1,2,(30,40))\nprint(hash(t1))\n\nt2 = (1,2,(30,40))\nprint(hash(t2))\n\nt3 = (1,2,frozenset([30,40]))\nprint(hash(t3))', 't3': (1, 2, frozenset({40, 30})), '_i7': "a = dict(one=1, two=2)\nb = {'one':1, 'two':2}\nc = dict(zip(['one','two'],[1,2]))\nd = dict([('two',2),('one',1)])\ne = dict({'two':2, 'one':1})\na == b == c == d == e", 'a': {'one': 1, 'two': 2}, 'b': {'one': 1, 'two': 2}, 'c': {'one': 1, 'two': 2}, 'e': {'two': 2, 'one': 1}, '_7': True, '_i8': "DIAL_CODES = [\n    (86, 'China'),\n    (91, 'India'),\n    (1, 'United States'),\n    (7, 'Russia'),\n    (81, 'Japan'),\n    (55, 'Brazil'),\n    (234, 'Nigeria')\n]", 'DIAL_CODES': [(86, 'China'), (91, 'India'), (1, 'United States'), (7, 'Russia'), (81, 'Japan'), (55, 'Brazil'), (234, 'Nigeria')], '_i9': 'country_codes = {country:code for code, country in DIAL_CODES}\nprint(country_codes)', 'country_codes': {'China': 86, 'India': 91, 'United States': 1, 'Russia': 7, 'Japan': 81, 'Brazil': 55, 'Nigeria': 234}, '_i10': '{code:country.upper() for country, code in country_codes.items() if code < 66}', '_10': {1: 'UNITED STATES', 7: 'RUSSIA', 55: 'BRAZIL'}, '_i11': 'inventory = {"apples": 430, "bananas": 312, "oranges": 525, "pears": 217}\n\ndel inventory["oranges"]\n\nprint(inventory)', 'inventory': {'apples': 430, 'bananas': 312, 'oranges': 525, 'pears': 217}, '_i12': 'inventory["pears"] = 0\nprint(inventory)', '_i13': 'inventory["oranges"] = 0\n\nprint(len(inventory))\nprint(inventory)', '_i14': 'for k in eng2sp.keys(): \n   print("Got key", k, "which maps to value", eng2sp[k])\n\nprint(type(eng2sp.keys()))\nks = list(eng2sp.keys())\nprint(ks)', 'k': 'two', 'ks': ['three', 'one', 'two'], '_i15': 'for k in eng2sp:\n   print("Got key", k)', '_i16': 'print(list(eng2sp.values()))\n\nprint(list(eng2sp.items()))', '_i17': 'for (k,v) in eng2sp.items():\n    print("Got",k,"that maps to",v)', 'v': 'dos', '_i18': 'inventory = {\'apples\': 430, \'bananas\': 312, \'oranges\': 525, \'pears\': 217}\n\nprint(inventory.get("apples"))\nprint(inventory.get("cherries"))\n\nprint(inventory.get("cherries", 0))', '_i19': 'inventory = {\'apples\': 430, \'bananas\': 312, \'oranges\': 525, \'pears\': 217}\nprint(\'apples\' in inventory)\nprint(\'cherries\' not in inventory)\n\nif \'bananas\' in inventory:\n    print(inventory[\'bananas\'])\nelse:\n    print("We have no bananas")', '_i20': 'alreadyknown = {0: 0, 1: 1}\n\ndef fib(n):\n    if n not in alreadyknown:\n        new_value = fib(n-1) + fib(n-2)\n        alreadyknown[n] = new_value\n    return alreadyknown[n]\n\nfib(35)', 'alreadyknown': {0: 0, 1: 1, 2: 1, 3: 2, 4: 3, 5: 5, 6: 8, 7: 13, 8: 21, 9: 34, 10: 55, 11: 89, 12: 144, 13: 233, 14: 377, 15: 610, 16: 987, 17: 1597, 18: 2584, 19: 4181, 20: 6765, 21: 10946, 22: 17711, 23: 28657, 24: 46368, 25: 75025, 26: 121393, 27: 196418, 28: 317811, 29: 514229, 30: 832040, 31: 1346269, 32: 2178309, 33: 3524578, 34: 5702887, 35: 9227465, 36: 14930352, 37: 24157817, 38: 39088169, 39: 63245986, 40: 102334155, 41: 165580141, 42: 267914296, 43: 433494437, 44: 701408733, 45: 1134903170, 46: 1836311903, 47: 2971215073, 48: 4807526976, 49: 7778742049, 50: 12586269025, 51: 20365011074, 52: 32951280099, 53: 53316291173, 54: 86267571272, 55: 139583862445, 56: 225851433717, 57: 365435296162, 58: 591286729879, 59: 956722026041, 60: 1548008755920, 61: 2504730781961, 62: 4052739537881, 63: 6557470319842, 64: 10610209857723, 65: 17167680177565, 66: 27777890035288, 67: 44945570212853, 68: 72723460248141, 69: 117669030460994, 70: 190392490709135, 71: 308061521170129, 72: 498454011879264, 73: 806515533049393, 74: 1304969544928657, 75: 2111485077978050, 76: 3416454622906707, 77: 5527939700884757, 78: 8944394323791464, 79: 14472334024676221, 80: 23416728348467685, 81: 37889062373143906, 82: 61305790721611591, 83: 99194853094755497, 84: 160500643816367088, 85: 259695496911122585, 86: 420196140727489673, 87: 679891637638612258, 88: 1100087778366101931, 89: 1779979416004714189, 90: 2880067194370816120, 91: 4660046610375530309, 92: 7540113804746346429, 93: 12200160415121876738, 94: 19740274219868223167, 95: 31940434634990099905, 96: 51680708854858323072, 97: 83621143489848422977, 98: 135301852344706746049, 99: 218922995834555169026, 100: 354224848179261915075}, 'fib': <function fib at 0x7f990853f048>, '_20': 9227465, '_i21': 'alreadyknown = {0: 0, 1: 1}\n\ndef fib(n):\n    if n not in alreadyknown:\n        new_value = fib(n-1) + fib(n-2)\n        alreadyknown[n] = new_value\n    return alreadyknown[n]\n\nfib(100)', '_21': 354224848179261915075, '_i22': '%%timeit \n\nfib(100)', '_i23': 'def countLetters(text):\n    counts = {}\n\n    for l in text:\n        counts[l] = counts.get(l, 0) + 1\n    \n    return counts', 'countLetters': <function countLetters at 0x7f99085277b8>, '_i24': "t = 'Such a frequency table might be useful for compressing a text file.'\n\ncounts = countLetters(t)\n\nprint(counts)", 't': 'Such a frequency table might be useful for compressing a text file.', 'counts': {'S': 1, 'u': 4, 'c': 3, 'h': 2, ' ': 11, 'a': 3, 'f': 4, 'r': 3, 'e': 8, 'q': 1, 'n': 2, 'y': 1, 't': 4, 'b': 2, 'l': 3, 'm': 2, 'i': 3, 'g': 2, 's': 3, 'o': 2, 'p': 1, 'x': 1, '.': 1}, '_i25': 'c_items = list(counts.items())\nc_items.sort()\nprint(c_items)', 'c_items': [(' ', 11), ('.', 1), ('S', 1), ('a', 3), ('b', 2), ('c', 3), ('e', 8), ('f', 4), ('g', 2), ('h', 2), ('i', 3), ('l', 3), ('m', 2), ('n', 2), ('o', 2), ('p', 1), ('q', 1), ('r', 3), ('s', 3), ('t', 4), ('u', 4), ('x', 1), ('y', 1)], '_i26': "from collections import OrderedDict\n# regular unsorted dictionary\nd = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}\n\n# dictionary sorted by key\nprint(OrderedDict(sorted(d.items(), key=lambda t: t[0])))\n\n# dictionary sorted by value\nprint( OrderedDict(sorted(d.items(), key=lambda t: t[1])))\n\n# dictionary sorted by length of the key string\nprint( OrderedDict(sorted(d.items(), key=lambda t: len(t[0]))))", 'OrderedDict': <class 'collections.OrderedDict'>, '_i27': 'import builtins\nfrom collections import ChainMap\npylookup = ChainMap(locals(), globals(), vars(builtins))\nprint(pylookup)', 'builtins': <module 'builtins' (built-in)>, 'ChainMap': <class 'collections.ChainMap'>, 'pylookup': ...}, {'__name__': '__main__', '__doc__': 'Automatically created module for IPython interactive environment', '__package__': None, '__loader__': None, '__spec__': None, '__builtin__': <module 'builtins' (built-in)>, '__builtins__': <module 'builtins' (built-in)>, '_ih': ['', 'eng2sp = {}\neng2sp["one"] = "uno"\neng2sp["two"] = "dos"\neng2sp["three"] = "tres"\nprint(eng2sp)', 'from IPython.display import IFrame\nIFrame("http://pythontutor.com/iframe-embed.html#code=eng2sp%20%3D%20%7B%7D%0Aeng2sp%5B%22one%22%5D%20%3D%20%22uno%22%0Aeng2sp%5B%22two%22%5D%20%3D%20%22dos%22%0Aeng2sp%5B%22three%22%5D%20%3D%20%22tres%22&codeDivHeight=400&codeDivWidth=350&cumulative=false&curInstr=0&heapPrimitives=false&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false", width=\'100%\', height=450)', "eng2sp = {'three': 'tres', 'one': 'uno', 'two': 'dos'}\nvalue = eng2sp['two']\nprint(value)", 'd = {"apples": 430, "bananas": 312, \n     "oranges": 525, "pears": 217}\n\nl = [(\'apples\', 430), (\'bananas\', 312),\n     (\'oranges\', 525), (\'pears\', 217)]', '#Hashable types: str, bytes, int, float, frozenset\nt1 = (1,2,(30,40))\nprint(hash(t1))\n\nt2 = (1,2,[30,40])\nprint(hash(t2))\n\nt3 = (1,2,frozenset([30,40]))\nprint(hash(t3))', '#Hashable types: str, bytes, int, float, frozenset\nt1 = (1,2,(30,40))\nprint(hash(t1))\n\nt2 = (1,2,(30,40))\nprint(hash(t2))\n\nt3 = (1,2,frozenset([30,40]))\nprint(hash(t3))', "a = dict(one=1, two=2)\nb = {'one':1, 'two':2}\nc = dict(zip(['one','two'],[1,2]))\nd = dict([('two',2),('one',1)])\ne = dict({'two':2, 'one':1})\na == b == c == d == e", "DIAL_CODES = [\n    (86, 'China'),\n    (91, 'India'),\n    (1, 'United States'),\n    (7, 'Russia'),\n    (81, 'Japan'),\n    (55, 'Brazil'),\n    (234, 'Nigeria')\n]", 'country_codes = {country:code for code, country in DIAL_CODES}\nprint(country_codes)', '{code:country.upper() for country, code in country_codes.items() if code < 66}', 'inventory = {"apples": 430, "bananas": 312, "oranges": 525, "pears": 217}\n\ndel inventory["oranges"]\n\nprint(inventory)', 'inventory["pears"] = 0\nprint(inventory)', 'inventory["oranges"] = 0\n\nprint(len(inventory))\nprint(inventory)', 'for k in eng2sp.keys(): \n   print("Got key", k, "which maps to value", eng2sp[k])\n\nprint(type(eng2sp.keys()))\nks = list(eng2sp.keys())\nprint(ks)', 'for k in eng2sp:\n   print("Got key", k)', 'print(list(eng2sp.values()))\n\nprint(list(eng2sp.items()))', 'for (k,v) in eng2sp.items():\n    print("Got",k,"that maps to",v)', 'inventory = {\'apples\': 430, \'bananas\': 312, \'oranges\': 525, \'pears\': 217}\n\nprint(inventory.get("apples"))\nprint(inventory.get("cherries"))\n\nprint(inventory.get("cherries", 0))', 'inventory = {\'apples\': 430, \'bananas\': 312, \'oranges\': 525, \'pears\': 217}\nprint(\'apples\' in inventory)\nprint(\'cherries\' not in inventory)\n\nif \'bananas\' in inventory:\n    print(inventory[\'bananas\'])\nelse:\n    print("We have no bananas")', 'alreadyknown = {0: 0, 1: 1}\n\ndef fib(n):\n    if n not in alreadyknown:\n        new_value = fib(n-1) + fib(n-2)\n        alreadyknown[n] = new_value\n    return alreadyknown[n]\n\nfib(35)', 'alreadyknown = {0: 0, 1: 1}\n\ndef fib(n):\n    if n not in alreadyknown:\n        new_value = fib(n-1) + fib(n-2)\n        alreadyknown[n] = new_value\n    return alreadyknown[n]\n\nfib(100)', "get_ipython().run_cell_magic('timeit', '', '\\nfib(100)\\n')", 'def countLetters(text):\n    counts = {}\n\n    for l in text:\n        counts[l] = counts.get(l, 0) + 1\n    \n    return counts', "t = 'Such a frequency table might be useful for compressing a text file.'\n\ncounts = countLetters(t)\n\nprint(counts)", 'c_items = list(counts.items())\nc_items.sort()\nprint(c_items)', "from collections import OrderedDict\n# regular unsorted dictionary\nd = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}\n\n# dictionary sorted by key\nprint(OrderedDict(sorted(d.items(), key=lambda t: t[0])))\n\n# dictionary sorted by value\nprint( OrderedDict(sorted(d.items(), key=lambda t: t[1])))\n\n# dictionary sorted by length of the key string\nprint( OrderedDict(sorted(d.items(), key=lambda t: len(t[0]))))", 'import builtins\nfrom collections import ChainMap\npylookup = ChainMap(locals(), globals(), vars(builtins))\nprint(pylookup)'], '_oh': {2: <IPython.lib.display.IFrame object at 0x7f98f8151400>, 7: True, 10: {1: 'UNITED STATES', 7: 'RUSSIA', 55: 'BRAZIL'}, 20: 9227465, 21: 354224848179261915075}, '_dh': ['/Users/caodg/Workspace/Course/Python/ic/notebooks'], 'In': ['', 'eng2sp = {}\neng2sp["one"] = "uno"\neng2sp["two"] = "dos"\neng2sp["three"] = "tres"\nprint(eng2sp)', 'from IPython.display import IFrame\nIFrame("http://pythontutor.com/iframe-embed.html#code=eng2sp%20%3D%20%7B%7D%0Aeng2sp%5B%22one%22%5D%20%3D%20%22uno%22%0Aeng2sp%5B%22two%22%5D%20%3D%20%22dos%22%0Aeng2sp%5B%22three%22%5D%20%3D%20%22tres%22&codeDivHeight=400&codeDivWidth=350&cumulative=false&curInstr=0&heapPrimitives=false&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false", width=\'100%\', height=450)', "eng2sp = {'three': 'tres', 'one': 'uno', 'two': 'dos'}\nvalue = eng2sp['two']\nprint(value)", 'd = {"apples": 430, "bananas": 312, \n     "oranges": 525, "pears": 217}\n\nl = [(\'apples\', 430), (\'bananas\', 312),\n     (\'oranges\', 525), (\'pears\', 217)]', '#Hashable types: str, bytes, int, float, frozenset\nt1 = (1,2,(30,40))\nprint(hash(t1))\n\nt2 = (1,2,[30,40])\nprint(hash(t2))\n\nt3 = (1,2,frozenset([30,40]))\nprint(hash(t3))', '#Hashable types: str, bytes, int, float, frozenset\nt1 = (1,2,(30,40))\nprint(hash(t1))\n\nt2 = (1,2,(30,40))\nprint(hash(t2))\n\nt3 = (1,2,frozenset([30,40]))\nprint(hash(t3))', "a = dict(one=1, two=2)\nb = {'one':1, 'two':2}\nc = dict(zip(['one','two'],[1,2]))\nd = dict([('two',2),('one',1)])\ne = dict({'two':2, 'one':1})\na == b == c == d == e", "DIAL_CODES = [\n    (86, 'China'),\n    (91, 'India'),\n    (1, 'United States'),\n    (7, 'Russia'),\n    (81, 'Japan'),\n    (55, 'Brazil'),\n    (234, 'Nigeria')\n]", 'country_codes = {country:code for code, country in DIAL_CODES}\nprint(country_codes)', '{code:country.upper() for country, code in country_codes.items() if code < 66}', 'inventory = {"apples": 430, "bananas": 312, "oranges": 525, "pears": 217}\n\ndel inventory["oranges"]\n\nprint(inventory)', 'inventory["pears"] = 0\nprint(inventory)', 'inventory["oranges"] = 0\n\nprint(len(inventory))\nprint(inventory)', 'for k in eng2sp.keys(): \n   print("Got key", k, "which maps to value", eng2sp[k])\n\nprint(type(eng2sp.keys()))\nks = list(eng2sp.keys())\nprint(ks)', 'for k in eng2sp:\n   print("Got key", k)', 'print(list(eng2sp.values()))\n\nprint(list(eng2sp.items()))', 'for (k,v) in eng2sp.items():\n    print("Got",k,"that maps to",v)', 'inventory = {\'apples\': 430, \'bananas\': 312, \'oranges\': 525, \'pears\': 217}\n\nprint(inventory.get("apples"))\nprint(inventory.get("cherries"))\n\nprint(inventory.get("cherries", 0))', 'inventory = {\'apples\': 430, \'bananas\': 312, \'oranges\': 525, \'pears\': 217}\nprint(\'apples\' in inventory)\nprint(\'cherries\' not in inventory)\n\nif \'bananas\' in inventory:\n    print(inventory[\'bananas\'])\nelse:\n    print("We have no bananas")', 'alreadyknown = {0: 0, 1: 1}\n\ndef fib(n):\n    if n not in alreadyknown:\n        new_value = fib(n-1) + fib(n-2)\n        alreadyknown[n] = new_value\n    return alreadyknown[n]\n\nfib(35)', 'alreadyknown = {0: 0, 1: 1}\n\ndef fib(n):\n    if n not in alreadyknown:\n        new_value = fib(n-1) + fib(n-2)\n        alreadyknown[n] = new_value\n    return alreadyknown[n]\n\nfib(100)', "get_ipython().run_cell_magic('timeit', '', '\\nfib(100)\\n')", 'def countLetters(text):\n    counts = {}\n\n    for l in text:\n        counts[l] = counts.get(l, 0) + 1\n    \n    return counts', "t = 'Such a frequency table might be useful for compressing a text file.'\n\ncounts = countLetters(t)\n\nprint(counts)", 'c_items = list(counts.items())\nc_items.sort()\nprint(c_items)', "from collections import OrderedDict\n# regular unsorted dictionary\nd = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}\n\n# dictionary sorted by key\nprint(OrderedDict(sorted(d.items(), key=lambda t: t[0])))\n\n# dictionary sorted by value\nprint( OrderedDict(sorted(d.items(), key=lambda t: t[1])))\n\n# dictionary sorted by length of the key string\nprint( OrderedDict(sorted(d.items(), key=lambda t: len(t[0]))))", 'import builtins\nfrom collections import ChainMap\npylookup = ChainMap(locals(), globals(), vars(builtins))\nprint(pylookup)'], 'Out': {2: <IPython.lib.display.IFrame object at 0x7f98f8151400>, 7: True, 10: {1: 'UNITED STATES', 7: 'RUSSIA', 55: 'BRAZIL'}, 20: 9227465, 21: 354224848179261915075}, 'get_ipython': <bound method InteractiveShell.get_ipython of <ipykernel.zmqshell.ZMQInteractiveShell object at 0x7f9918719b70>>, 'exit': <IPython.core.autocall.ZMQExitAutocall object at 0x7f98e84856a0>, 'quit': <IPython.core.autocall.ZMQExitAutocall object at 0x7f98e84856a0>, '_': 354224848179261915075, '__': 9227465, '___': {1: 'UNITED STATES', 7: 'RUSSIA', 55: 'BRAZIL'}, '_i': "from collections import OrderedDict\n# regular unsorted dictionary\nd = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}\n\n# dictionary sorted by key\nprint(OrderedDict(sorted(d.items(), key=lambda t: t[0])))\n\n# dictionary sorted by value\nprint( OrderedDict(sorted(d.items(), key=lambda t: t[1])))\n\n# dictionary sorted by length of the key string\nprint( OrderedDict(sorted(d.items(), key=lambda t: len(t[0]))))", '_ii': 'c_items = list(counts.items())\nc_items.sort()\nprint(c_items)', '_iii': "t = 'Such a frequency table might be useful for compressing a text file.'\n\ncounts = countLetters(t)\n\nprint(counts)", '_i1': 'eng2sp = {}\neng2sp["one"] = "uno"\neng2sp["two"] = "dos"\neng2sp["three"] = "tres"\nprint(eng2sp)', 'eng2sp': {'three': 'tres', 'one': 'uno', 'two': 'dos'}, '_i2': 'from IPython.display import IFrame\nIFrame("http://pythontutor.com/iframe-embed.html#code=eng2sp%20%3D%20%7B%7D%0Aeng2sp%5B%22one%22%5D%20%3D%20%22uno%22%0Aeng2sp%5B%22two%22%5D%20%3D%20%22dos%22%0Aeng2sp%5B%22three%22%5D%20%3D%20%22tres%22&codeDivHeight=400&codeDivWidth=350&cumulative=false&curInstr=0&heapPrimitives=false&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false", width=\'100%\', height=450)', 'IFrame': <class 'IPython.lib.display.IFrame'>, '_2': <IPython.lib.display.IFrame object at 0x7f98f8151400>, '_i3': "eng2sp = {'three': 'tres', 'one': 'uno', 'two': 'dos'}\nvalue = eng2sp['two']\nprint(value)", 'value': 'dos', '_i4': 'd = {"apples": 430, "bananas": 312, \n     "oranges": 525, "pears": 217}\n\nl = [(\'apples\', 430), (\'bananas\', 312),\n     (\'oranges\', 525), (\'pears\', 217)]', 'd': {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}, 'l': [('apples', 430), ('bananas', 312), ('oranges', 525), ('pears', 217)], '_i5': '#Hashable types: str, bytes, int, float, frozenset\nt1 = (1,2,(30,40))\nprint(hash(t1))\n\nt2 = (1,2,[30,40])\nprint(hash(t2))\n\nt3 = (1,2,frozenset([30,40]))\nprint(hash(t3))', 't1': (1, 2, (30, 40)), 't2': (1, 2, (30, 40)), '_i6': '#Hashable types: str, bytes, int, float, frozenset\nt1 = (1,2,(30,40))\nprint(hash(t1))\n\nt2 = (1,2,(30,40))\nprint(hash(t2))\n\nt3 = (1,2,frozenset([30,40]))\nprint(hash(t3))', 't3': (1, 2, frozenset({40, 30})), '_i7': "a = dict(one=1, two=2)\nb = {'one':1, 'two':2}\nc = dict(zip(['one','two'],[1,2]))\nd = dict([('two',2),('one',1)])\ne = dict({'two':2, 'one':1})\na == b == c == d == e", 'a': {'one': 1, 'two': 2}, 'b': {'one': 1, 'two': 2}, 'c': {'one': 1, 'two': 2}, 'e': {'two': 2, 'one': 1}, '_7': True, '_i8': "DIAL_CODES = [\n    (86, 'China'),\n    (91, 'India'),\n    (1, 'United States'),\n    (7, 'Russia'),\n    (81, 'Japan'),\n    (55, 'Brazil'),\n    (234, 'Nigeria')\n]", 'DIAL_CODES': [(86, 'China'), (91, 'India'), (1, 'United States'), (7, 'Russia'), (81, 'Japan'), (55, 'Brazil'), (234, 'Nigeria')], '_i9': 'country_codes = {country:code for code, country in DIAL_CODES}\nprint(country_codes)', 'country_codes': {'China': 86, 'India': 91, 'United States': 1, 'Russia': 7, 'Japan': 81, 'Brazil': 55, 'Nigeria': 234}, '_i10': '{code:country.upper() for country, code in country_codes.items() if code < 66}', '_10': {1: 'UNITED STATES', 7: 'RUSSIA', 55: 'BRAZIL'}, '_i11': 'inventory = {"apples": 430, "bananas": 312, "oranges": 525, "pears": 217}\n\ndel inventory["oranges"]\n\nprint(inventory)', 'inventory': {'apples': 430, 'bananas': 312, 'oranges': 525, 'pears': 217}, '_i12': 'inventory["pears"] = 0\nprint(inventory)', '_i13': 'inventory["oranges"] = 0\n\nprint(len(inventory))\nprint(inventory)', '_i14': 'for k in eng2sp.keys(): \n   print("Got key", k, "which maps to value", eng2sp[k])\n\nprint(type(eng2sp.keys()))\nks = list(eng2sp.keys())\nprint(ks)', 'k': 'two', 'ks': ['three', 'one', 'two'], '_i15': 'for k in eng2sp:\n   print("Got key", k)', '_i16': 'print(list(eng2sp.values()))\n\nprint(list(eng2sp.items()))', '_i17': 'for (k,v) in eng2sp.items():\n    print("Got",k,"that maps to",v)', 'v': 'dos', '_i18': 'inventory = {\'apples\': 430, \'bananas\': 312, \'oranges\': 525, \'pears\': 217}\n\nprint(inventory.get("apples"))\nprint(inventory.get("cherries"))\n\nprint(inventory.get("cherries", 0))', '_i19': 'inventory = {\'apples\': 430, \'bananas\': 312, \'oranges\': 525, \'pears\': 217}\nprint(\'apples\' in inventory)\nprint(\'cherries\' not in inventory)\n\nif \'bananas\' in inventory:\n    print(inventory[\'bananas\'])\nelse:\n    print("We have no bananas")', '_i20': 'alreadyknown = {0: 0, 1: 1}\n\ndef fib(n):\n    if n not in alreadyknown:\n        new_value = fib(n-1) + fib(n-2)\n        alreadyknown[n] = new_value\n    return alreadyknown[n]\n\nfib(35)', 'alreadyknown': {0: 0, 1: 1, 2: 1, 3: 2, 4: 3, 5: 5, 6: 8, 7: 13, 8: 21, 9: 34, 10: 55, 11: 89, 12: 144, 13: 233, 14: 377, 15: 610, 16: 987, 17: 1597, 18: 2584, 19: 4181, 20: 6765, 21: 10946, 22: 17711, 23: 28657, 24: 46368, 25: 75025, 26: 121393, 27: 196418, 28: 317811, 29: 514229, 30: 832040, 31: 1346269, 32: 2178309, 33: 3524578, 34: 5702887, 35: 9227465, 36: 14930352, 37: 24157817, 38: 39088169, 39: 63245986, 40: 102334155, 41: 165580141, 42: 267914296, 43: 433494437, 44: 701408733, 45: 1134903170, 46: 1836311903, 47: 2971215073, 48: 4807526976, 49: 7778742049, 50: 12586269025, 51: 20365011074, 52: 32951280099, 53: 53316291173, 54: 86267571272, 55: 139583862445, 56: 225851433717, 57: 365435296162, 58: 591286729879, 59: 956722026041, 60: 1548008755920, 61: 2504730781961, 62: 4052739537881, 63: 6557470319842, 64: 10610209857723, 65: 17167680177565, 66: 27777890035288, 67: 44945570212853, 68: 72723460248141, 69: 117669030460994, 70: 190392490709135, 71: 308061521170129, 72: 498454011879264, 73: 806515533049393, 74: 1304969544928657, 75: 2111485077978050, 76: 3416454622906707, 77: 5527939700884757, 78: 8944394323791464, 79: 14472334024676221, 80: 23416728348467685, 81: 37889062373143906, 82: 61305790721611591, 83: 99194853094755497, 84: 160500643816367088, 85: 259695496911122585, 86: 420196140727489673, 87: 679891637638612258, 88: 1100087778366101931, 89: 1779979416004714189, 90: 2880067194370816120, 91: 4660046610375530309, 92: 7540113804746346429, 93: 12200160415121876738, 94: 19740274219868223167, 95: 31940434634990099905, 96: 51680708854858323072, 97: 83621143489848422977, 98: 135301852344706746049, 99: 218922995834555169026, 100: 354224848179261915075}, 'fib': <function fib at 0x7f990853f048>, '_20': 9227465, '_i21': 'alreadyknown = {0: 0, 1: 1}\n\ndef fib(n):\n    if n not in alreadyknown:\n        new_value = fib(n-1) + fib(n-2)\n        alreadyknown[n] = new_value\n    return alreadyknown[n]\n\nfib(100)', '_21': 354224848179261915075, '_i22': '%%timeit \n\nfib(100)', '_i23': 'def countLetters(text):\n    counts = {}\n\n    for l in text:\n        counts[l] = counts.get(l, 0) + 1\n    \n    return counts', 'countLetters': <function countLetters at 0x7f99085277b8>, '_i24': "t = 'Such a frequency table might be useful for compressing a text file.'\n\ncounts = countLetters(t)\n\nprint(counts)", 't': 'Such a frequency table might be useful for compressing a text file.', 'counts': {'S': 1, 'u': 4, 'c': 3, 'h': 2, ' ': 11, 'a': 3, 'f': 4, 'r': 3, 'e': 8, 'q': 1, 'n': 2, 'y': 1, 't': 4, 'b': 2, 'l': 3, 'm': 2, 'i': 3, 'g': 2, 's': 3, 'o': 2, 'p': 1, 'x': 1, '.': 1}, '_i25': 'c_items = list(counts.items())\nc_items.sort()\nprint(c_items)', 'c_items': [(' ', 11), ('.', 1), ('S', 1), ('a', 3), ('b', 2), ('c', 3), ('e', 8), ('f', 4), ('g', 2), ('h', 2), ('i', 3), ('l', 3), ('m', 2), ('n', 2), ('o', 2), ('p', 1), ('q', 1), ('r', 3), ('s', 3), ('t', 4), ('u', 4), ('x', 1), ('y', 1)], '_i26': "from collections import OrderedDict\n# regular unsorted dictionary\nd = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}\n\n# dictionary sorted by key\nprint(OrderedDict(sorted(d.items(), key=lambda t: t[0])))\n\n# dictionary sorted by value\nprint( OrderedDict(sorted(d.items(), key=lambda t: t[1])))\n\n# dictionary sorted by length of the key string\nprint( OrderedDict(sorted(d.items(), key=lambda t: len(t[0]))))", 'OrderedDict': <class 'collections.OrderedDict'>, '_i27': 'import builtins\nfrom collections import ChainMap\npylookup = ChainMap(locals(), globals(), vars(builtins))\nprint(pylookup)', 'builtins': <module 'builtins' (built-in)>, 'ChainMap': <class 'collections.ChainMap'>, 'pylookup': ...}, {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", '__package__': '', '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': ModuleSpec(name='builtins', loader=<class '_frozen_importlib.BuiltinImporter'>), '__build_class__': <built-in function __build_class__>, '__import__': <built-in function __import__>, 'abs': <built-in function abs>, 'all': <built-in function all>, 'any': <built-in function any>, 'ascii': <built-in function ascii>, 'bin': <built-in function bin>, 'breakpoint': <built-in function breakpoint>, 'callable': <built-in function callable>, 'chr': <built-in function chr>, 'compile': <built-in function compile>, 'delattr': <built-in function delattr>, 'dir': <built-in function dir>, 'divmod': <built-in function divmod>, 'eval': <built-in function eval>, 'exec': <built-in function exec>, 'format': <built-in function format>, 'getattr': <built-in function getattr>, 'globals': <built-in function globals>, 'hasattr': <built-in function hasattr>, 'hash': <built-in function hash>, 'hex': <built-in function hex>, 'id': <built-in function id>, 'input': <bound method Kernel.raw_input of <ipykernel.ipkernel.IPythonKernel object at 0x7f98e83f5dd8>>, 'isinstance': <built-in function isinstance>, 'issubclass': <built-in function issubclass>, 'iter': <built-in function iter>, 'len': <built-in function len>, 'locals': <built-in function locals>, 'max': <built-in function max>, 'min': <built-in function min>, 'next': <built-in function next>, 'oct': <built-in function oct>, 'ord': <built-in function ord>, 'pow': <built-in function pow>, 'print': <built-in function print>, 'repr': <built-in function repr>, 'round': <built-in function round>, 'setattr': <built-in function setattr>, 'sorted': <built-in function sorted>, 'sum': <built-in function sum>, 'vars': <built-in function vars>, 'None': None, 'Ellipsis': Ellipsis, 'NotImplemented': NotImplemented, 'False': False, 'True': True, 'bool': <class 'bool'>, 'memoryview': <class 'memoryview'>, 'bytearray': <class 'bytearray'>, 'bytes': <class 'bytes'>, 'classmethod': <class 'classmethod'>, 'complex': <class 'complex'>, 'dict': <class 'dict'>, 'enumerate': <class 'enumerate'>, 'filter': <class 'filter'>, 'float': <class 'float'>, 'frozenset': <class 'frozenset'>, 'property': <class 'property'>, 'int': <class 'int'>, 'list': <class 'list'>, 'map': <class 'map'>, 'object': <class 'object'>, 'range': <class 'range'>, 'reversed': <class 'reversed'>, 'set': <class 'set'>, 'slice': <class 'slice'>, 'staticmethod': <class 'staticmethod'>, 'str': <class 'str'>, 'super': <class 'super'>, 'tuple': <class 'tuple'>, 'type': <class 'type'>, 'zip': <class 'zip'>, '__debug__': True, 'BaseException': <class 'BaseException'>, 'Exception': <class 'Exception'>, 'TypeError': <class 'TypeError'>, 'StopAsyncIteration': <class 'StopAsyncIteration'>, 'StopIteration': <class 'StopIteration'>, 'GeneratorExit': <class 'GeneratorExit'>, 'SystemExit': <class 'SystemExit'>, 'KeyboardInterrupt': <class 'KeyboardInterrupt'>, 'ImportError': <class 'ImportError'>, 'ModuleNotFoundError': <class 'ModuleNotFoundError'>, 'OSError': <class 'OSError'>, 'EnvironmentError': <class 'OSError'>, 'IOError': <class 'OSError'>, 'EOFError': <class 'EOFError'>, 'RuntimeError': <class 'RuntimeError'>, 'RecursionError': <class 'RecursionError'>, 'NotImplementedError': <class 'NotImplementedError'>, 'NameError': <class 'NameError'>, 'UnboundLocalError': <class 'UnboundLocalError'>, 'AttributeError': <class 'AttributeError'>, 'SyntaxError': <class 'SyntaxError'>, 'IndentationError': <class 'IndentationError'>, 'TabError': <class 'TabError'>, 'LookupError': <class 'LookupError'>, 'IndexError': <class 'IndexError'>, 'KeyError': <class 'KeyError'>, 'ValueError': <class 'ValueError'>, 'UnicodeError': <class 'UnicodeError'>, 'UnicodeEncodeError': <class 'UnicodeEncodeError'>, 'UnicodeDecodeError': <class 'UnicodeDecodeError'>, 'UnicodeTranslateError': <class 'UnicodeTranslateError'>, 'AssertionError': <class 'AssertionError'>, 'ArithmeticError': <class 'ArithmeticError'>, 'FloatingPointError': <class 'FloatingPointError'>, 'OverflowError': <class 'OverflowError'>, 'ZeroDivisionError': <class 'ZeroDivisionError'>, 'SystemError': <class 'SystemError'>, 'ReferenceError': <class 'ReferenceError'>, 'MemoryError': <class 'MemoryError'>, 'BufferError': <class 'BufferError'>, 'Warning': <class 'Warning'>, 'UserWarning': <class 'UserWarning'>, 'DeprecationWarning': <class 'DeprecationWarning'>, 'PendingDeprecationWarning': <class 'PendingDeprecationWarning'>, 'SyntaxWarning': <class 'SyntaxWarning'>, 'RuntimeWarning': <class 'RuntimeWarning'>, 'FutureWarning': <class 'FutureWarning'>, 'ImportWarning': <class 'ImportWarning'>, 'UnicodeWarning': <class 'UnicodeWarning'>, 'BytesWarning': <class 'BytesWarning'>, 'ResourceWarning': <class 'ResourceWarning'>, 'ConnectionError': <class 'ConnectionError'>, 'BlockingIOError': <class 'BlockingIOError'>, 'BrokenPipeError': <class 'BrokenPipeError'>, 'ChildProcessError': <class 'ChildProcessError'>, 'ConnectionAbortedError': <class 'ConnectionAbortedError'>, 'ConnectionRefusedError': <class 'ConnectionRefusedError'>, 'ConnectionResetError': <class 'ConnectionResetError'>, 'FileExistsError': <class 'FileExistsError'>, 'FileNotFoundError': <class 'FileNotFoundError'>, 'IsADirectoryError': <class 'IsADirectoryError'>, 'NotADirectoryError': <class 'NotADirectoryError'>, 'InterruptedError': <class 'InterruptedError'>, 'PermissionError': <class 'PermissionError'>, 'ProcessLookupError': <class 'ProcessLookupError'>, 'TimeoutError': <class 'TimeoutError'>, 'open': <built-in function open>, 'copyright': Copyright (c) 2001-2018 Python Software Foundation.
All Rights Reserved.

Copyright (c) 2000 BeOpen.com.
All Rights Reserved.

Copyright (c) 1995-2001 Corporation for National Research Initiatives.
All Rights Reserved.

Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.
All Rights Reserved., 'credits':     Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
    for supporting Python development.  See www.python.org for more information., 'license': Type license() to see the full license text, 'help': Type help() for interactive help, or help(object) for help about object., '__IPYTHON__': True, 'display': <function display at 0x7f990824ac80>, 'get_ipython': <bound method InteractiveShell.get_ipython of <ipykernel.zmqshell.ZMQInteractiveShell object at 0x7f9918719b70>>})
In [28]:
import collections 
  
dic1 = { 'a' : 1, 'b' : 2 } 
dic2 = { 'b' : 3, 'c' : 4 } 
  
chain = collections.ChainMap(dic1, dic2) 
  
print (chain.maps) 
  
print (list(chain.keys())) 
  
print (list(chain.values())) 
[{'a': 1, 'b': 2}, {'b': 3, 'c': 4}]
['b', 'c', 'a']
[2, 4, 1]
In [29]:
import collections 
  
dic1 = { 'a' : 1, 'b' : 2 } 
dic2 = { 'b' : 3, 'c' : 4 } 
dic3 = { 'f' : 5 } 
  
chain = collections.ChainMap(dic1, dic2) 
print (chain.maps) 
  
chain1 = chain.new_child(dic3) 
print (chain1.maps) 
print ("Value associated with b before reversing is : ",end="") 
print (chain1['b']) 
  
chain1.maps = reversed(chain1.maps) 
print ("Value associated with b after reversing is : ",end="") 
print (chain1['b']) 
[{'a': 1, 'b': 2}, {'b': 3, 'c': 4}]
[{'f': 5}, {'a': 1, 'b': 2}, {'b': 3, 'c': 4}]
Value associated with b before reversing is : 2
Value associated with b after reversing is : 3

collections.Counter

A Counter is a dict subclass for counting hashable objects. It is a collection where elements are stored as dictionary keys and their counts are stored as dictionary values.

In [30]:
ct = collections.Counter('abracadabra')
print(ct)
ct.update('aaaaazzz')
print(ct)
print(ct.most_common(2))
Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})
Counter({'a': 10, 'z': 3, 'b': 2, 'r': 2, 'c': 1, 'd': 1})
[('a', 10), ('z', 3)]
In [31]:
c = collections.Counter(a=3, b=1)
d = collections.Counter(a=1, b=2)
print(c + d)   # add two counters together:  c[x] + d[x]
print(c - d)   # subtract (keeping only positive counts)
print(c & d)   # intersection:  min(c[x], d[x]) # doctest: +SKIP
print(c | d)   # union:  max(c[x], d[x])
Counter({'a': 4, 'b': 3})
Counter({'a': 2})
Counter({'a': 1, 'b': 1})
Counter({'a': 3, 'b': 2})

collections.UserDict

Class that simulates a dictionary. It is designed to be subclassed.

In [ ]:
import collections

class StrKeyDict(collections.UserDict):
    
    def __missing__(self,key):
        if isinstance(key,str):
            raise KeyError(key)
        return self[str(key)]
    
    def __contains__(self,key):
        return str(key) in self.data
    
    def __setitem__(self, key, item):
        self.data[str(key)] = item

Exercise

Write a Python program to combine values in python list of dictionaries.

Sample data: [{'item': 'item1', 'amount': 400}, {'item': 'item2', 'amount': 300}, {'item': 'item1', 'amount': 750}]

Expected Output: Counter({'item1': 1150, 'item2': 300})

In [32]:
from collections import Counter
item_list = [{'item': 'item1', 'amount': 400}, {'item': 'item2', 'amount': 300}, {'item': 'item1', 'amount': 750}]
result = Counter()
for d in item_list:
    result[d['item']] += d['amount']
print(result) 
Counter({'item1': 1150, 'item2': 300})
In [33]:
item_list = [{'item': 'item1', 'amount': 400}, {'item': 'item2', 'amount': 300}, {'item': 'item1', 'amount': 750}]
result = {}
for d in item_list:
    if d['item'] in result:
        result [d['item']] += d['amount']
    else:
        result [d['item']] = d['amount']
print(result) 
{'item1': 1150, 'item2': 300}

Glossary

dictionary

A collection of key-value pairs that maps from keys to values. The keys can be any immutable type, and the values can be any type.

key

A data item that is mapped to a value in a dictionary. Keys are used to look up values in a dictionary.

key-value pair

One of the pairs of items in a dictionary. Values are looked up in a dictionary by key.

mapping type

A mapping type is a data type comprised of a collection of keys and associated values. Python’s only built-in mapping type is the dictionary. Dictionaries implement the associative array abstract data type.

In [ ]: