mutating dictionaries (slides)

CSc 110 - mutating dictionaries

Dictionaries are mutable

  • changes to a dictionary in a function will remain after the function finishes running
  • you can change dictionary values using keys

Changing values in a dictionary

You can change dictionary values using keys

names_ages = {"Paul": 32, "Patricia": 44, "Eduardo": 27}
for key in names_ages:
  names_ages[key] += 1
names_ages
{'Paul': 33, 'Patricia': 45, 'Eduardo': 28}

Write a function

It mutates the dictionary, multiplying each value by 0.056 and rounding the result to two decimals

Name file as sales_tax.py and submit to Gradescope

groceries = {"banana": 2.50, "milk": 4.25, "bread": 3.68}
sales_tax(groceries)
assert groceries == {'banana': 0.14, 'milk': 0.24, 'bread': 0.21}

Write a function – solution

def sales_tax(dictionary):
  for key in dictionary:
    dictionary[key] = round(dictionary[key] * 0.056, 2)
  return dictionary

def main():
  groceries = {"banana": 2.50, "milk": 4.25, "bread": 3.68}
  sales_tax(groceries)
  assert groceries == {'banana': 0.14, 'milk': 0.24, 'bread': 0.21}
  print(groceries)
  
main()
{'banana': 0.14, 'milk': 0.24, 'bread': 0.21}

Removing dictionary key: value

Cannot iterate over a dictionary and change its size:

counts = {"a": 10, "e": 4, "i": 3}
for key in counts:
  counts.pop(key)

RuntimeError: dictionary changed size during iteration

Removing dictionary key: value

  • Step 1: use another data structure (like a set) instead
  • Step 2: iterate that data structure
counts = {"a": 10, "e": 4, "i": 3}
keys = set(counts)
for k in keys:
  counts.pop(k)
counts
{}

Write a function

It takes a dictionary as argument, with string keys. It mutates and returns the dictionary argument removing keys that start and end with the same character

students = {"Anna": "A", "Peter": "B", "Bob": "D", "Cedric": "A"}
remove_records(students)
assert students == {"Peter": "B"}

Write a function – solution

def remove_records(dictionary):
  for k in set(dictionary):
    if len(k) > 0 and k[0].lower() == k[-1].lower():
      dictionary.pop(k)
  return dictionary
      
def main():
  students = {"Anna": "A", "Peter": "B", "Bob": "D", "Cedric": "A"}
  remove_records(students)
  assert students == {"Peter": "B"}
  
main()

Create a list with duplicate items

Create a list with a total of five 'a':

new_list = ['a'] * 5
new_list
['a', 'a', 'a', 'a', 'a']

Create a list with a total of three 1:

new_list = [1] * 3
new_list
[1, 1, 1]

Write a function

It takes a dictionary as argument, with strings as keys and integers as values (assume all values are positive). It mutates and returns the dictionary, replacing each value with a list of the key repeated by the value.

test_dictionary = {"a": 5, "b": 2, "c": 3}
repetition(test_dictionary)
assert test_dictionary == {"a": ["a", "a", "a", "a", "a"], 
                           "b": ["b", "b"], "c": ["c", "c", "c"] }

Write a function – solution

def repetition(dictionary):
  for key, value in dictionary.items():
    dictionary[key] = [key] * value
  return dictionary

def main():
  test_dictionary = {"a": 5, "b": 2, "c": 3}
  repetition(test_dictionary)
  assert test_dictionary == {"a": ["a", "a", "a", "a", "a"], 
                           "b": ["b", "b"], "c": ["c", "c", "c"] }
  
main()

Write a function

It has two parameters: a dictionary that maps one-letter strings to lists of strings, and a string. It returns a list with strings (names) from the lists in the dictionary that include the second parameter (string) as a substring (this search is not case sensitive)

Test case:

names = {"R": ["Randy", "Roger"], "S": ["Steve", "Sally"], "T": ["Tanner"]}
assert get_names(names, "er") == ["Roger", "Tanner"]

Write a function – solution

def get_names(dictionary, string):
  new_list = []
  for name_list in dictionary.values():
    for name in name_list:
      if string.lower() in name.lower():
        new_list.append(name)
  return new_list

def main():
  names = { "R": ["Randy", "Roger"], 
            "S": ["Steve", "Sally"], 
            "T": ["Tanner"] }
  print( get_names(names, "er") ) # ["Roger", "Tanner"]
  
main()
['Roger', 'Tanner']

Quiz 11

current time

You have 10 minutes to complete the quiz.