## 1. Reviewing Sequences¶

We have seen four kinds of sequences so far: strings, lists, ranges, and tuples.
Python can distinguish among them via their delimiters: quotes for strings, square brackets for lists, and parentheses for tuples.

In [1]:
phrase = "Quincy's quilters quit quilting quickly"     # a string
numbers = [0, 10, 20, 30, 40, 50]                      # a list of numbers
courses = ["CS 111", "CS 115", "CS 121"
"CS 204", "CS 220", "CS 230"]               # a list of strings
person = ('Frederick', 'Douglass')                     # a tuple of strings
date = ('November', 8, 20201)                          # a mixed tuple
odds = range(1, 10, 2)                                 # a range of numbers

In [2]:
print("type of 'phrase':", type(phrase))
print("type of 'numbers':", type(numbers))
print("type of 'characters':", type(courses))
print("type of 'person':", type(person))
print("type of 'date':", type(date))
print("type of 'odds':", type(odds))

type of 'phrase': <class 'str'>
type of 'numbers': <class 'list'>
type of 'characters': <class 'list'>
type of 'person': <class 'tuple'>
type of 'date': <class 'tuple'>
type of 'odds': <class 'range'>


### Common Operations for Sequences¶

Sequences share many operations:

• subscripting with indices,
• slicing (with colon),
• checking for membership with in,
• use of len to indicate length
• iteration through loops

a) Examples of indexing
Outputs in this case are a single element of the sequence.

In [3]:
phrase[14] # access element at index 14

Out[3]:
'e'
In [4]:
numbers[3] # access element at index 3

Out[4]:
30
In [5]:
person[1]  # access element at index 1

Out[5]:
'Douglass'
In [6]:
odds[2] # access element at index 2

Out[6]:
5

b) Examples of slicing
Outputs in this case are subsequences.

In [7]:
phrase[4:13] # slicing - get the elements indexed from 4 to 13 (this is not included)

Out[7]:
"cy's quil"
In [8]:
date[:2] # slicing - get the first two elements of the tuple

Out[8]:
('November', 8)
In [9]:
numbers[2:] # slicing - get all elements starting at index 2

Out[9]:
[20, 30, 40, 50]
In [10]:
odds[1::2] # slicing - get every other odd number starting at index 1

Out[10]:
range(3, 11, 4)

b) Examples of using the membership operator in
Outputs are boolean values.

In [11]:
2015 in date

Out[11]:
False
In [12]:
50 in numbers

Out[12]:
True
In [13]:
'quit' in phrase

Out[13]:
True
In [14]:
4 in odds

Out[14]:
False

### Reminder: Why do we care about tuples?¶

Tuples are often used in Python to do multiple assignments in one single statement:

In [15]:
a, b = 0, 1
a, b

Out[15]:
(0, 1)
In [16]:
0, 1

Out[16]:
(0, 1)

Python generates tuples whenever we use commas to separate values:

In [17]:
len(phrase), len(numbers), len(courses), len(person), len(date), len(odds)

Out[17]:
(39, 6, 5, 2, 3, 5)

## 2. Introducing Dictionaries¶

Dictionaries are unordered (see note below) collections that map keys to values:

In [18]:
daysOfMonth = {'Jan': 31, 'Feb': 28, 'Mar': 31, 'Apr': 30,
'May': 31, 'Jun': 30, 'Jul': 31, 'Aug': 31,
'Sep': 30, 'Oct': 31, 'Nov': 30} # one month is missing
daysOfMonth

Out[18]:
{'Jan': 31,
'Feb': 28,
'Mar': 31,
'Apr': 30,
'May': 31,
'Jun': 30,
'Jul': 31,
'Aug': 31,
'Sep': 30,
'Oct': 31,
'Nov': 30}

Note: Dictionaries behind the scenes do actually maintain the order in which keys/values were inserted into the dictionary. This explains why, when we run the cell above, the months are outputted in the same order they were written. But you should not treat dictionaries as an ordered collection in the same way you would a sequence like a list. You cannot access a dictionary by index. You cannot append to a dictionary because a dictionary does not have a "last" item. Therefore, conceptually you should treat the key-value pairs as unordered elements in the dictionary.

## 3. Adding and Removing from Dictionaries¶

### 3.1 Literal dicts¶

We can write the entire dictionary as a literal value by wrapping braces around a comma-separate sequence of key:value pairs:

In [19]:
student = {'name': 'Georgia Dome', 'dorm': 'Munger Hall',
'section': 2,
'year': 2023,
'CSMajor?': True}

student

Out[19]:
{'name': 'Georgia Dome',
'dorm': 'Munger Hall',
'section': 2,
'year': 2023,
'CSMajor?': True}
In [21]:
len(student)

Out[21]:
5
In [22]:
# a dictionary may have different types as keys and values
mixedLabelDict = {"orange": "fruit",
3: "March",
"even": [2,4,6,8]}
mixedLabelDict

Out[22]:
{'orange': 'fruit', 3: 'March', 'even': [2, 4, 6, 8]}

### 3.2 Growing Dictionaries and Mutability¶

Dictionaries are mutable. This means we can start with an empty dictionary and grow it in much the same way we do a list. This is a common way to create dictionaries in many of our problems.

In [23]:
cart = {} # The empty dictionary
cart['oreos'] = 3.99
cart['kiwis'] = 2.54

cart

Out[23]:
{'oreos': 3.99, 'kiwis': 2.54}

Note: Since dictionaries are unordered, the order in which we enter key/value pairs is irrelevant.

Recall that the dictionary above was missing the month of december which has 31 days. Add that to the daysOfMonth dictionary below.

In [24]:
# Your code here
daysOfMonth['Dec'] = 31


### 3.3 The pop method¶

Given a key, the pop method on a dictionary removes the key/value pair with that key from the dictionary and returns the value formerly associated with the key. pop mutates the dictionary.

In [25]:
cart.pop('oreos')

Out[25]:
3.99
In [26]:
cart

Out[26]:
{'kiwis': 2.54}

QUESTION: It looks like the method pop works similarly to the one for lists. Do you think it will behave the same if we don't provide an argument value for it? Explain.

### 3.4 Accessing Dictionaries With The Subscripting Operator¶

We do this not with indices, but with keys.

In [27]:
daysOfMonth['May']

Out[27]:
31

IMPORTANT Note that we don't have to loop through the key/value pairs to find the value associated with the key. We just use the key as the subscript, and the dictionary "magically" returns the corresponding values. This is easy and powerful!

Trying to look for a key that doesn't exist...

In [28]:
daysOfMonth['October']

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-28-66ac62b8a356> in <module>
----> 1 daysOfMonth['October']

KeyError: 'October'

Note: Indexing with 0, 1, ..., will not work, the same way 'October' didn't work, because subscription is based only on the keys.

In [29]:
daysOfMonth[0]

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-29-dc45923b543c> in <module>
----> 1 daysOfMonth[0]

KeyError: 0

### 3.5 Check if a key exists with the operator in¶

The operator in can be used with dictionaries just like with sequence types.
We can check if a key is in a dictionary, by typing: key in someDict. However, this doesn't work with values.

In [30]:
'Oct' in daysOfMonth

Out[30]:
True
In [31]:
31 in daysOfMonth

Out[31]:
False
In [32]:
if 'October' in daysOfMonth:
print(daysOfMonth['October'])
else:

Key not found


### Your Turn: Create a simple dictionary¶

1. Define a dictionary named person that has two keys: 'first' and 'last' and as corresponding values your own first and last names.
2. Use this dict in a print statement to display: Well done, FIRST LAST! (where FIRST and LAST are your first and last names read from the dictionary).
In [33]:
# create dict
person = {'first': 'Katherine', 'last': 'Johnson'}

In [34]:
# print phrase
print("Well done, " + person['first'], person['last'] + "!")

Well done, Katherine Johnson!


### 3.6 More examples of dictionaries¶

We''ll use these dictionaries in following examples in this notebook, so don't forget to run this cell.

In [35]:
student = {'name': 'Georgia Dome',
'dorm': 'Munger Hall',
'section': 2,
'year': 2023,
'CSMajor?': True}

'Trevor Noah': 9996541212,
'Paula A. Johnson': 7811234567}

('Grace', 'Hopper'):['grace@wellesley.edu', 1906],
('Margaret', 'Hamilton'):['margaret@wellesley.edu', 1936],
('Katherine', 'Johnson'):['katherine@wellesley.edu', 1918]}

# these are contributions of edits by Wikipedia editors

contributions = {
'uma52': {2015: 10, 2016: 15},
'setam$3': {2012: 23, 2013: 34, 2014: 17}, 'rid12': {2009: 5, 2010: 18, 2012: 4} }  The dictionary computerScientists contains four important women in the field of computer science. Check out their Wikipedia pages below to learn more about them: 1. Ada Lovelace: One of the first programmers and credited with writing the first computer program. 2. Grace Hopper: One of the pioneers of compilers (programs that translate one computer language to another) and the COBOL programming language. 3. Margaret Hamilton): Her team developed the onboard flight software for the Apollo Missions and was director of the Software Engineering Division of the MIT Instrumentation Labratory. 4. Katherine Johnson: An American Mathematician whose prowess in calculating orbital mechanics was essential in verifying calculations by early computers used in NASA flight missions. One of the first African American women to work as a NASA scientist. President Barack Obama awarded all three American women the Presidential Medal of Freedom. ### Your Turn: Subscripting dictionaries¶ In [36]: student  Out[36]: {'name': 'Georgia Dome', 'dorm': 'Munger Hall', 'section': 2, 'year': 2023, 'CSMajor?': True} In [37]: # write the expression to retrieve the value 2023 from student # Your code here student['year']  Out[37]: 2023 In [38]: phones  Out[38]: {'Gal Gadot': 5558671234, 'Trevor Noah': 9996541212, 'Paula A. Johnson': 7811234567} In [39]: # write the expression to retrive Gal Gadot's phone number from phones # Your code here phones['Gal Gadot']  Out[39]: 5558671234 In [40]: computerScientists  Out[40]: {('Ada', 'Lovelace'): ['ada@wellesley.edu', 1815], ('Grace', 'Hopper'): ['grace@wellesley.edu', 1906], ('Margaret', 'Hamilton'): ['margaret@wellesley.edu', 1936], ('Katherine', 'Johnson'): ['katherine@wellesley.edu', 1918]} In [41]: # write the expression to retrieve Grace Hopper's information from computerScientists # Your code here computerScientists[('Grace', 'Hopper')]  Out[41]: ['grace@wellesley.edu', 1906] In [44]: # what does this return? computerScientists[('Ada', 'Lovelace')][0][0]  Out[44]: 'a' ### 3.7 Changing key-value pairs in a dictionary¶ When a key is already in a dictionary, assigning a value to that key in the dictionary changes the value at that key. For example, the key Feb is associated with what value in the daysOfMonth dictionary? In [45]: daysOfMonth  Out[45]: {'Jan': 31, 'Feb': 28, 'Mar': 31, 'Apr': 30, 'May': 31, 'Jun': 30, 'Jul': 31, 'Aug': 31, 'Sep': 30, 'Oct': 31, 'Nov': 30, 'Dec': 31} In [46]: daysOfMonth['Feb']  Out[46]: 28 If it's a leap year, we can change the value associated with Feb to be 29 via assignment with the subscript: In [47]: daysOfMonth['Feb'] = 29 # change value associated with a key  In [48]: daysOfMonth  Out[48]: {'Jan': 31, 'Feb': 29, 'Mar': 31, 'Apr': 30, 'May': 31, 'Jun': 30, 'Jul': 31, 'Aug': 31, 'Sep': 30, 'Oct': 31, 'Nov': 30, 'Dec': 31} In [49]: daysOfMonth['Feb']  Out[49]: 29 ### 3.8 Dictionary keys must be immutable¶ Although dictionaries are mutable, the keys of dictionaries must be immutable. In [53]: daysOfMonth[['Feb', 2021]] = 28 # try to use a key that has month and year in a list  --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-53-692103ac9cdf> in <module> ----> 1 daysOfMonth[['Feb', 2021]] = 28 # try to use a key that has month and year in a list TypeError: unhashable type: 'list' But the following works, because a tuple is immutable: In [55]: daysOfMonth[('Feb', 2021)] = 28 daysOfMonth  Out[55]: {'Jan': 31, 'Feb': 29, 'Mar': 31, 'Apr': 30, 'May': 31, 'Jun': 30, 'Jul': 31, 'Aug': 31, 'Sep': 30, 'Oct': 31, 'Nov': 30, 'Dec': 31, ('Feb', 2021): 28} Reminder that you can remove keys using pop. But here we need to use the entire key as a tuple in order to remove it. In [56]: daysOfMonth.pop(('Feb', 2021))  Out[56]: 28 In [57]: daysOfMonth  Out[57]: {'Jan': 31, 'Feb': 29, 'Mar': 31, 'Apr': 30, 'May': 31, 'Jun': 30, 'Jul': 31, 'Aug': 31, 'Sep': 30, 'Oct': 31, 'Nov': 30, 'Dec': 31} The computerScientists dictionary is an example of a dictionary with tuples as keys. In [58]: computerScientists  Out[58]: {('Ada', 'Lovelace'): ['ada@wellesley.edu', 1815], ('Grace', 'Hopper'): ['grace@wellesley.edu', 1906], ('Margaret', 'Hamilton'): ['margaret@wellesley.edu', 1936], ('Katherine', 'Johnson'): ['katherine@wellesley.edu', 1918]} ## 4. Getting the keys and values¶ In [59]: daysOfMonth # the entire dict  Out[59]: {'Jan': 31, 'Feb': 29, 'Mar': 31, 'Apr': 30, 'May': 31, 'Jun': 30, 'Jul': 31, 'Aug': 31, 'Sep': 30, 'Oct': 31, 'Nov': 30, 'Dec': 31} ### The methods keys, values, and items¶ Sometimes we are interested in knowing these parts of the dictionary. Each of these methods returns an object containing only the keys, values, and items, respectively. In [60]: daysOfMonth.keys()  Out[60]: dict_keys(['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']) Note that the order of elements in the list is not predictable. In [61]: type(daysOfMonth.keys())  Out[61]: dict_keys Note that the .keys(), .values(), and .items() methods each return a different type of object. In [62]: daysOfMonth.values()  Out[62]: dict_values([31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]) In [63]: type(daysOfMonth.values())  Out[63]: dict_values The list returned by .values() is synchronized with the list returned by .keys(). You can find corresponding months and days in the same index. In [64]: daysOfMonth.items()  Out[64]: dict_items([('Jan', 31), ('Feb', 29), ('Mar', 31), ('Apr', 30), ('May', 31), ('Jun', 30), ('Jul', 31), ('Aug', 31), ('Sep', 30), ('Oct', 31), ('Nov', 30), ('Dec', 31)]) In [65]: type(daysOfMonth.items())  Out[65]: dict_items The objects of type dict_keys, dict_values, and dict_items are so-called dictionary views that reflect any subsequent changes to the underlying dictionary from which they were made. In [66]: numNames = {'one': 1, 'two': 2, 'three': 3} ks = numNames.keys() vs = numNames.values() its = numNames.items() print('keys:', ks) print('values:', vs) print('items:', its)  keys: dict_keys(['one', 'two', 'three']) values: dict_values([1, 2, 3]) items: dict_items([('one', 1), ('two', 2), ('three', 3)])  In [67]: numNames['four'] = 4 print('keys:', ks) print('values:', vs) print('items:', its)  keys: dict_keys(['one', 'two', 'three', 'four']) values: dict_values([1, 2, 3, 4]) items: dict_items([('one', 1), ('two', 2), ('three', 3), ('four', 4)])  In [68]: numNames.pop('one') print('keys:', ks) print('values:', vs) print('items:', its)  keys: dict_keys(['two', 'three', 'four']) values: dict_values([2, 3, 4]) items: dict_items([('two', 2), ('three', 3), ('four', 4)])  ## 5. Iterating over a dictionary¶ There are many ways to iterate over a dictionary: 1. over the keys (do not use .keys()) 2. over the values (with .values()) 3. over the items (with .items()) In [69]: phones  Out[69]: {'Gal Gadot': 5558671234, 'Trevor Noah': 9996541212, 'Paula A. Johnson': 7811234567} In [70]: # iterate directly (by default Python goes over the keys, because they are unique) for key in phones: print(key, phones[key])  Gal Gadot 5558671234 Trevor Noah 9996541212 Paula A. Johnson 7811234567  Using for to iterate over a dictionary means iterating over all the keys in the dictionary, so there is no need to use .keys(), which would create an unnecessary object. So we prefer to write for key in phones: rather than for key in phones.keys():. In [71]: for key in phones: print(key, phones[key])  Gal Gadot 5558671234 Trevor Noah 9996541212 Paula A. Johnson 7811234567  In [72]: for val in phones.values(): print("Call " + str(val) + "!")  Call 5558671234! Call 9996541212! Call 7811234567!  In [74]: # sometimes is useful to iterate over the items directly # notice the tuple assignment in the for loop for name, number in phones.items(): print(f"Call {name} at {number}.")  Call Gal Gadot at 5558671234. Call Trevor Noah at 9996541212. Call Paula A. Johnson at 7811234567.  QUESTION: Can we go from values to keys, as we did from keys to values? What can we say about keys and values in a dictionary? In [ ]: daysOfMonth = {'Jan': 31, 'Feb': 28, 'Mar': 31, 'Apr': 30, 'May': 31, 'Jun': 30, 'Jul': 31, 'Aug': 31, 'Sep': 30, 'Oct': 31, 'Nov': 30, 'Dec': 31}  In [75]: for month, days in daysOfMonth.items(): print(f"{month} has {days} days.")  Jan has 31 days. Feb has 29 days. Mar has 31 days. Apr has 30 days. May has 31 days. Jun has 30 days. Jul has 31 days. Aug has 31 days. Sep has 30 days. Oct has 31 days. Nov has 30 days. Dec has 31 days.  ## 6. Exercise 1: rewrite scrabblePoints¶ A great use for dictionaries is to store data that can simplify choosing among different values. Here is a scrabblePoints function. In [76]: def scrabblePoints(letter): "Return the scrabble score associated with a letter." if letter in 'aeilnorstu': return 1 elif letter in 'dg': return 2 elif letter in 'bcmp': return 3 elif letter in 'fhvwy': return 4 elif letter in 'k': return 5 elif letter in 'jx': return 8 elif letter in 'qz': return 10 return 0 for letter in 'abdhjkq': print(f"{letter} is worth {scrabblePoints(letter)} points.")  a is worth 1 points. b is worth 3 points. d is worth 2 points. h is worth 4 points. j is worth 8 points. k is worth 5 points. q is worth 10 points.  We'll start by storing the letter and their points in a dictionary: In [77]: scrabbleDict = {'a': 1, 'b': 3, 'c': 3, 'd': 2, 'e': 1, 'f': 4, 'g': 2, 'h': 4, 'i': 1, 'j': 8, 'k': 5, 'l': 1, 'm': 3, 'n': 1, 'o': 1, 'p': 3, 'q': 10, 'r': 1, 's': 1, 't': 1, 'u': 1, 'v': 4, 'w': 4, 'x': 8, 'y': 4, 'z': 10}  In [78]: def scrabblePoints2(letter): "Return the scrabble score associated with a letter." # Algorithm # 1. If letter is in scrabbleDict, return its points # 2. Otherwise return 0 # Your code here if letter in scrabbleDict: return scrabbleDict[letter] return 0  In [79]: # Test with different values for letter in 'abdhjkq7!': print(f"{letter} is worth, {scrabblePoints2(letter)} points.")  a is worth, 1 points. b is worth, 3 points. d is worth, 2 points. h is worth, 4 points. j is worth, 8 points. k is worth, 5 points. q is worth, 10 points. 7 is worth, 0 points. ! is worth, 0 points.  ## 7. Exercise 2: Word Frequencies¶ In [80]: def frequencies(wordList): """Given a list of words, returns a dictionary of word frequencies""" # Algorithm # 1. create an empty dict # 2. iterate through the words of the given list # 3. set the value or increment the value for each word # 4. return the dict # Your code here freqDict = {} for word in wordList: if word in freqDict: freqDict[word] += 1 else: freqDict[word] = 1 return freqDict  In [81]: frequencies(["house", "bird", "house", "chirp", "feather", "chirp", "chirp"])  Out[81]: {'house': 2, 'bird': 1, 'chirp': 3, 'feather': 1} ## 8. Exercise 3: Find largest value¶ Write the function getKeyWithMaxValue that behaves as shown below: In [2]: getKeyWithMaxValue({'A': 0.25, 'E': 0.36, 'I': 0.16, 'O': 0.18, 'U': 0.05}) Out[2]: 'E' Hint: Remember the built-in function max; when given a list, it returns the largest value in the list. Also, remember the method values for a dictionary. In [82]: def getKeyWithMaxValue(dct): """Given a dict whose values are numbers, return the key that corresponds to the highest value. """ # One possible algorithm: # 1. find the max with the help of the .values method # 2. iterate through the keys to find which key has a value that is equal to max # 3. return that key (it can be an early return) # Your code here maxVal = max(dct.values()) for letter in dct: if dct[letter] == maxVal: return letter  In [83]: getKeyWithMaxValue({'A': 0.25, 'E': 0.36, 'I': 0.16, 'O': 0.18, 'U': 0.05})  Out[83]: 'E' ## 9. Exercise 4: Reverse Lookup¶ Write a function that takes a dict that has many similar values and creates a new dict where the keys are the unique values and the values are lists of the keys. Example: In [30]: results = {'Andy': 'bronze', 'Carolyn': 'gold', 'Peter': 'bronze', 'Sohie': 'silver'} In [30]: reverseDictionary(results) Out[31]: {'bronze': ['Andy', 'Peter'], 'gold': ['Carolyn'], 'silver': ['Sohie']} In [84]: def reverseDictionary(dct): """Given a dict that has many repeating values, returns a new dict where the old values become the new keys. The new values are lists containing all the old keys with the same value. """ # Algorithm # 1. Create an empty dict # 2. Iterate over the dictionary # 3. If a key exists, append to the corresponding value (which is a list) # 4. If not, create the key:value pair, by assigning a list with one element to the new key # 5. return dict # Your code here reverseDct = {} for key, value in dct.items(): if value in reverseDct: reverseDct[value].append(key) else: reverseDct[value] = [key] return reverseDct  In [85]: results = {'Andy': 'bronze', 'Carolyn': 'gold', 'Peter': 'bronze', 'Sohie': 'silver'} reverseDictionary(results)  Out[85]: {'bronze': ['Andy', 'Peter'], 'gold': ['Carolyn'], 'silver': ['Sohie']} ## 10. Exercise 5: reverse dictionary (month lengths)¶ How can you create the dictionary monthLengths with one single line of code? monthLengths = {31: ['Jan','Mar','May','Jul','Aug','Oct','Dec'], 30: ['Apr', 'Jun','Sep','Nov'], 28: ['Feb']} In [86]: # Your code here monthLengths = reverseDictionary(daysOfMonth) monthLengths  Out[86]: {31: ['Jan', 'Mar', 'May', 'Jul', 'Aug', 'Oct', 'Dec'], 29: ['Feb'], 30: ['Apr', 'Jun', 'Sep', 'Nov']} ## 11. Digging deeper and Other Additional Topics¶ ### Use the built-in dict function¶ The dict function can create a dictionary from a list of tuples, where every tuple has two elements. In [87]: dict([('DEU', 49), ('ALB', 355), ('UK', 44)]) # a list of tuples for country codes  Out[87]: {'DEU': 49, 'ALB': 355, 'UK': 44} A tuple that is not part of a list will not work: In [88]: dict(('USA', 1))  --------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-88-c30d6bfc189c> in <module> ----> 1 dict(('USA', 1)) ValueError: dictionary update sequence element #0 has length 3; 2 is required Calling dict with zero arguments creates an empty dictionary: In [89]: dict() # creates an empty dict  Out[89]: {} ### The get method¶ The method get is used to avoid the step of checking for a key before updating. This is possible because this method will return a "default" value when the key is not in the dictionary. In all other cases, it will return the value associated with the given key. In [90]: daysOfMonth  Out[90]: {'Jan': 31, 'Feb': 29, 'Mar': 31, 'Apr': 30, 'May': 31, 'Jun': 30, 'Jul': 31, 'Aug': 31, 'Sep': 30, 'Oct': 31, 'Nov': 30, 'Dec': 31} In [91]: daysOfMonth.get('Oct', 'unknown')  Out[91]: 31 In [92]: daysOfMonth.get('OCT', 'unknown')  Out[92]: 'unknown' Remember that if we try to access a non-existing key directly, we'll get a KeyError: In [93]: daysOfMonth['OCT']  --------------------------------------------------------------------------- KeyError Traceback (most recent call last) <ipython-input-93-13b9f48288b7> in <module> ----> 1 daysOfMonth['OCT'] KeyError: 'OCT' Using get, allows us to avoid that error: In [94]: daysOfMonth.get('OCT')  QUESTION: Why don't we see anything? ### The update method¶ dict1.update(dict2) mutates dict1 by assigning the key/value pairs of dict2 to dict1. In [95]: # let's remind ourselves of the contributions contributions  Out[95]: {'uma52': {2015: 10, 2016: 15}, 'setam$3': {2012: 23, 2013: 34, 2014: 17},
'rid12': {2009: 5, 2010: 18, 2012: 4}}
In [96]:
newContributions = {'brix4': {2011: 39, 2013: 27, 2015: 41},
'uma52': {2017: 21}}

In [97]:
contributions.update(newContributions)


QUESTION: What didn't you see an output from running the cell above?

In [98]:
contributions

Out[98]:
{'uma52': {2017: 21},
'setam\$3': {2012: 23, 2013: 34, 2014: 17},
'rid12': {2009: 5, 2010: 18, 2012: 4},
'brix4': {2011: 39, 2013: 27, 2015: 41}}

QUESTION: Why did the 2015 and 2016 contributions for uma52 disappear?

### The clear method¶

We can wipe out the content of a dictionary with clear:

In [99]:
letters = {"a" : 1, "b" : 2}

In [100]:
letters.clear()
letters

Out[100]:
{}

### What does "hashable" mean?¶

When Python stores the keys of a dictionary in memory, it stores their hashes, which is an integer returned by the hash function. Only immutable objects can be hashed.

In [101]:
hash("Wellesley")

Out[101]:
5282091269197803170
In [102]:
hash(['Feb', 2015])

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-102-808a8ea426e9> in <module>
----> 1 hash(['Feb', 2015])

TypeError: unhashable type: 'list'
In [103]:
hash( ('Feb', 2015) ) # Tuples are hashable even though lists are not

Out[103]:
2952144978299312081
In [104]:
hash(123456) # numbers are their own hash value

Out[104]:
123456

At this point, you don't have to worry about why the keys are hashed, or how the hash function works!