**Homework 5: dictionaries** **Reed CSCI 121 Spring 2026** *complete the exercises by 9am on 2/3* This week's lab exercises are a mix of problems that have you work with Python lists and with Python dictionaries. We ask you to write a function for each of them. Let me just remind you that lists and dictionaries are both *passed by reference* to a function. This means that it is possible to change the values stored in them, and to increase and decrease their size by applying certain operations to them, within a function's code. These changes can be noticed by the client code that uses the function that changes them. Because of this ability to modify lists and dictionaries, you need to pay careful attention as to whether we want your function to change the data structure it is given, and also whether or not we want you to build and return a new data structure. (##) Dictionary syntax summary [Here is a summary](homework5-sheet.pdf) of (example) syntax for working with dictionaries (##) Working in pairs We will be pairing most of you up for the first two exercises. Pairs only need to turn in a single group submission to Gradescope. When you do submit an exercise solution on Gradescope, please make sure to select your programming partner in Gradescope. In pair programming, you work together on the same exercise. One person (the *driver*) does the actual coding in the editor and testing the code in the terminal. The other person (the *navigator*) makes suggestions and points out typos and other mistakes. They "have the driver's back," so to speak. The navigator also looks things up in notes and references other course resources. **Complete one exercise as the two roles and then switch for the next exercise.** Only work this way for exercises 1 and 2. Submit the remainder on your own. Even so, feel free to chat with your partner and with others on those other exercises. If you miss lab, please complete the lab assignment on your own. (#) Problems (##) `[Hw5 Ex1]` word count `=>` *To be done as a pair in lab. One person (the "driver") hands it in for your duo. If you miss lab hand it in on your own.* A Python string made up of words separated by spaces can be split into a list of strings made up of the words as they were strung together. To do so, you use a string operation called `split`, passing it the space character `' '` like so: ~~~ none >>> sentence = "the quick brown fox jumped over the lazy dogs" >>> print(sentence) the quick brown fox jumped over the lazy dogs >>> words = sentence.split(' ') >>> words ['the', 'quick', 'brown', 'fox', 'jumped', 'over', 'the', 'lazy', 'dogs'] >>> "hello there".split(' ') ['hello', 'there'] ~~~ Write a function `def word_count(s)` that takes a string `s` and gives back a dictionary that gives an integer count of the number of times each word appears in `s`. There should be a dictionary entry for every word that appears in `s` and each should have a value of 1 or more that corresponds to the number of times that word appears. ~~~ none >>> word_count("hello there") {'hello': 1, 'there': 1} >>> word_count("buffalo buffalo buffalo buffalo buffalo buffalo buffalo buffalo") {'buffalo': 8} >>> word_count("b a n a n a s") {'a': 3, 'b': 1, 'n': 2, 's': 1} >>> word_count("i am who i am as far as i know" {'as': 2, 'am': 2, 'far': 1, 'i': 3, 'know': 1, 'who': 1} ~~~ You can assume that the string consists of only the letters from `'a'` to `'z'` and spaces, that there are no spaces at the front or end of the string, and that there are never two consecutive spaces. Note that the ordering of dictionary entries produced by Python's report does not matter. Dictionary entries, unlike list entires, are unordered. This means that ~~~ none >>> word_count("hello there") {'there': 1, 'hello': 1} ~~~ is just as correct a result as the result listed before. (##) `[Hw5 Ex2]` word positions `=>` *To be done as a pair in lab. One person (the "driver") hands it in for your duo. If you miss lab hand it in on your own.* Now write a function `word_positions` that also returns a dictionary with an entry for each word that occurs in the text. Rather than a word count, it should instead give the list of positions where the word occurs in the text. (The first word in the text is at position 0.) ~~~ none >>> word_positions("hello there") {'hello': [0], 'there': [1]} >>> word_positions("buffalo buffalo buffalo buffalo buffalo buffalo buffalo buffalo") {'buffalo': [0, 1, 2, 3, 4, 5, 6, 7]} >>> word_positions("b a n a n a s") {'a': [1, 3, 5], 'b': [0], 'n': [2, 4], 's': [6]} >>> word_positions("i am who i am as far as i know") {'as': [5, 7], 'am': [1, 4], 'far': [6], 'i': [0, 3, 8], 'know': [9], 'who': [2]} ~~~ The positions should be listed in increasing odrer. (##) `[Hw5 Ex3]` replace `=>` *To be done on your own. Drive and navigate yourself. It's still okay to chat with others to discuss the work.* Write a function `replace` that takes a string of text and a dictionary. Each entry in the dictionary is a string with a list of strings. (Each key is a string and its associated value is a list of strings.) The function should return the string of text that results from replacing words with other words as given by the dictionary. For example, if we take the Python string ~~~none 'I heard that name verb activity and activity' ~~~ and the dictionary ~~~none {'name':['Adam','Jim','Erica'], 'activity ':['hiking ','biking ','liking '], 'verb ':['likes ','bikes ']} ~~~ then, fed these, `replace` would return the string ~~~none 'I heard that Adam likes hiking and biking' ~~~ If instead we fed `replace` the string ~~~none 'name verb that name is activity and name is activity' ~~~ with the same dictionary, it would return the string ~~~none 'Adam likes that Jim is hiking and Erica is biking' ~~~ Your `replace` function should draw replacement words from the list in each dictionary entry in the order they appear in that dictionary entry. (For example, in the last example above, the names are inserted into the string in the same order they appear in the dictionary entry: first `Adam`, then `Jim`, then `Erica`.) You can assume that there are enough words in each entry to perform the replacement on the given string. You can use `split` to convert the text into a list of strings, just like in Exercise 1. A list of strings can be joined together into a single string by using the string `join` operation as shown below ~~~ none >>> words = ['the', 'quick', 'brown', 'fox', 'jumped', 'over', 'the', 'lazy', 'dogs'] >>> sentence = ' '.join(words) >>> sentence 'the quick brown fox jumped over the lazy dogs' >>> ' '.join(['ba','nan','a','s']) 'ba nan a s' ~~~ You don't need to use `join`, but you might try it out if it is convenient for your approach. It is okay to modify the dictionary in order to perform the work of this function. (##) `[Hw5 Ex4]` inverse `=>` *To be done on your own. Drive and navigate yourself. It's still okay to chat with others to discuss the work.* Write a function `def inverse(d)` which takes a dictionary `d` and returns its "inverse" dictionary, a dictionary mapping values of entries in the given dictionary to lists of keys in the given dictionary. The keys of the dictionary it returns are the the values of the original dictionary and whose entries are lists of keys which mapped to that value in the original dictionary. For example: ~~~ none >>> inverse({'a':'b', 'c':'b', 'cats':'rest', 'world':'hello'}) {'hello':['world'], 'rest':['cats'], 'b':['a', 'c']} >>> inverse({}) {} >>> inverse({'a':'1','b':'1','c':'1','d':'1','e':'1','f':'1','g':'1'}) {'1':['e', 'c', 'f', 'g', 'a', 'd', 'b']} ~~~~ Note that the ordering of dictionary entries produced by Python's report does not matter. Dictionary entries, unlike list entires, are unordered. This means that ~~~ none >>> inverse({'a':'b', 'c':'b', 'cats':'rest', 'world':'hello'}) {'b':['a', 'c'], 'hello':['world'], 'rest':['cats']} ~~~ is just as correct a result as the result listed before. The ordering of the listed values in the inverse dictionary also does not matter. That means that the entry for `'b'` could instead have been `['c', 'a']` in the result reported just above.