010 Getting Started with Python#

COM6018

Copyright © 2023, 2024 Jon Barker, University of Sheffield. All rights reserved.

This notebook contains a number of exercises that will help you get started with Python. It is not intended to be a comprehensive introduction to Python, but rather a quick introduction to some of the features that you will need for this module.

At each stage there is a problem described for which you have to implement a solution in the following code cell. There is then a test cell which will run and check that your solution is correct. If it is correct, the test cell will print “Test passed”. If it is not correct, the test cell will print “Test failed” and give you some information about what went wrong.

1 Processing a list#

1.1 Summing a list of numbers#

Write a function called sum_list that takes a list of numbers as an argument and returns the sum of the numbers in the list. For example:

sum_list([1, 2, 3, 4, 5])

should return 15.

One approach to this is to use Python’s inbuilt sum function which takes a list of numbers as an argument and returns the sum of the numbers in the list. For example:

def sum_list(numbers):
    return sum(numbers)

For this exercise, write your solution from scratch without using the sum function but instead using a loop to iterate over the list and add the numbers together.

Implement your function in the cell below and then run the following cell to check that it works.

# WRITE SOLUTION HERE
# TESTS
assert sum_list([1, 2, 3, 4, 5]) == 15
assert sum_list([-100]) == -100
assert sum_list([]) == 0
print("All tests passed")

1.2. Product of a list of numbers#

Write a function called product_list that takes a list of numbers as an argument and returns the product of the numbers in the list.

For example:

product_list([1, 2, 3, 4, 5])

should return 120.

# WRITE SOLUTION HERE
# TESTS
assert product_list([1, 2, 3, 4, 5]) == 120
assert product_list([1, 2, -4, 0, 5]) == 0
assert product_list([]) == 1
print("All tests passed")

1.3. Finding all values greater than a threshold#

Write a Python function called greater_than that takes two arguments:

1.	`numbers`: a list of numbers.
2.	`threshold`: a number.

The function should return a new list containing all the numbers from numbers that are greater than the threshold.

For example:

greater_than([1, 2, 3, 4, 5], 3)

should return [4, 5].

Implement this function using a ‘for’ loop. i.e. iterate over the list and add each number that is greater than the threshold to a new list. You can add a number to a list by using the append method. For example:

my_list = []
my_list.append(1)
my_list.append(2)

Implement this solution in the cell below and then run the following cell to check that it works.

# WRITE SOLUTION HERE
# TESTS
assert greater_than([1, 2, 3, 4, 5], 3) == [4, 5]
assert greater_than([1, 2, 3, 4, 5], 5) == []
assert greater_than([1, 2, 3, 4, 5], 0) == [1, 2, 3, 4, 5]
print("All tests passed")

Now, implement the greater_than function again but this time using a list comprehension rather than an for loop. Check the tutorial on list comprehensions if you are not sure how to do this. Hint, you should be able to write the function with a single line.

Call your new function greater_than_lc, implement it in the cell below and then run the test cell to check that it works.

# WRITE SOLUTION HERE
# TESTS
assert greater_than_lc([1, 2, 3, 4, 5], 3) == [4, 5]
assert greater_than_lc([1, 2, 3, 4, 5], 5) == []
assert greater_than_lc([1, 2, 3, 4, 5], 0) == [1, 2, 3, 4, 5]
print("All tests passed")

We are now going to compare the speed of the two implementations. We will do this by using a very long list and the special %timeit magic function which is part of the Jupyter notebook environment. The %timeit function will run a piece of code a number of times and report the average time taken. Run the following cells to see how long it takes to run the two functions on a list of 1000000 numbers.

big_list = [x for x in range(1000000)]
%timeit greater_than(big_list, 500000)
%timeit greater_than_lc(big_list, 500000)

You should find that the version using the list comprehension is significantly faster than the version using the for loop. This is because the for loop version is appending each number to the list one element at a time. This is very slow.

In other contexts, for loops may run at about the same speed as list comprehensions. For example, let’s run the above experiment again but this time using a much higher threshold value so that the output list has no items.

%timeit greater_than(big_list, 1000000)
%timeit greater_than_lc(big_list, 1000000)

Notice that now that there are no items to add to the list, they both run faster but also that the speed difference between the for-loop version and the list comprehension version is much smaller.

1.4 Finding words with more than N characters#

Write a function called long_words that takes a list of words and a threshold value as arguments and returns a list of all the words in the list that have more than N characters.

For example:

long_words(['the', 'quick', 'brown', 'fox', 'jumped', 'over', 'the', 'lazy', 'dog'], 3)

should return ['quick', 'brown', 'jumped', 'over', 'lazy'].

# WRITE SOLUTION HERE
# TESTS
assert long_words(["hello", "world", "this", "is", "a", "test"], 3) == ["hello", "world", "this", "test"]
assert long_words(["hello", "world", "this", "is", "a", "test"], 4) == ["hello", "world"]
assert long_words(["hello", "world", "this", "is", "a", "test"], 0) == ["hello", "world", "this", "is", "a", "test"]
assert long_words(["hello", "world", "this", "is", "a", "test"], 5) == []
assert long_words([], 0) == []
print("All tests passed")

2 Searching a list#

2.1 Finding a specific value in a list#

Write a function called find_item that takes a list of values and an item to search for and returns the index of the first occurrence of the item in the list. The index should count from 0. If the item is not in the list, the function should return -1.

For example:

find_item([1, 2, 3, 4, 5], 3)

should return 2.

# WRITE SOLUTION HERE
# TESTS
assert find_item([1, 2, 3, 4, 5], 3) == 2
assert find_item([1, 2, 3, 4, 5], 1) == 0
assert find_item([1, 2, 3, 4, 5], 6) == -1
assert find_item([], 0) == -1
print("All tests passed")

2.2 Finding the maximum value in a list#

Write a function called max_item that takes a list of numbers and returns the maximum value in the list.

For example:

max_item([1, 2, 3, 4, 5])

should return 5.

Your function must not use the inbuilt max function.

You can assume that the list being passed to the function will always contain at least one item.

# WRITE SOLUTION HERE
# TESTS
assert max_item([1, 2, 3, 4, 5]) == 5
assert max_item([100, 2, 3, 4, 5]) == 100
assert max_item([3, 3, 3]) == 3
assert max_item([-1, -2, -3, -4, -5]) == -1
print("All tests passed")

2.3 Finding the closest value in a list#

Write a function named closest_value that takes a list and a target value and returns the value in the list that is closest to the target value.

For example:

closest_value([1, 2, 3, 4, 5], 3.2)

should return 3.

Again, you can assume that the list being passed to the function will always contain at least one item.

# WRITE SOLUTION HERE
# TESTS
assert closest_value([1, 2, 3, 4, 5], 3.2) == 3
assert closest_value([1, 2, 3, 4, 5], 3.8) == 4
assert closest_value([1, 2, 3, 4, 5], -1) == 1
assert closest_value([1, 2, 3, 4, 5], 10) == 5
print("All tests passed")

3. Applying functions to list values#

3.1 Squaring a list of numbers#

Write a function called square_list that takes a list of numbers and returns a new list where each number is the square of the corresponding number in the input list.

For example:

square_list([1, 2, 3, 4, 5])

should return [1, 4, 9, 16, 25].

# WRITE SOLUTION HERE
# TESTS
assert square_list([1, 2, 3, 4, 5]) == [1, 4, 9, 16, 25]
assert square_list([-1, -2, -3, -4, -5]) == [1, 4, 9, 16, 25]
assert square_list([]) == []
print("All tests passed")

3.2 Applying a function to a list of numbers#

In Python you can pass functions as arguments to other functions.

Write a function called apply_to_list that takes a list of numbers and a function as arguments and returns a new list with the function applied to each number in the list.

For example:

def square(x):
    return x * x

apply_to_list([1, 2, 3, 4, 5], square)

should return [1, 4, 9, 16, 25].

For hints, see Section 3 of the tutorial on Further Python.

# WRITE SOLUTION HERE
# TESTS
def square(x):
    return x**2

assert apply_to_list([1, 2, 3, 4, 5],  square) == [1, 4, 9, 16, 25]
assert apply_to_list([-1, -2, -3, -4, -5],  square) == [1, 4, 9, 16, 25]
assert apply_to_list([], square) == []
print("All tests passed")

3.3 Computing numbers in the hailstone sequence#

Write a function called hailstone that returns the next number in the hailstone sequence for a list of numbers. The hailstone sequence is defined as follows:

  • If the number is even, divide it by two.

  • If the number is odd, multiply it by three and add one.

Then write a function called hailstone_list that takes a list of numbers and returns a new list with the next number in the hailstone sequence for each number in the list.

For example:

hailstone_list([1, 2, 3, 4, 5])

should return [4, 1, 10, 2, 16].

# WRITE SOLUTION HERE
# TESTS
assert hailstone_list([1,2,3,4,5,6,7,8,9,10]) == [4,1,10,2,16,3,22,4,28,5]
print("All tests passed")

Now, write a loop that calls the hailstone_list function 100 times in a row. Here’s what the loop should do:

  1. Use the output of one call as the input for the next:

  • In each iteration of the loop, the list returned from the hailstone_list function should be passed as input to the next call of the function.

  1. Repeat this process 100 times:

  • Keep applying the function, updating the list in each iteration.

What do you notice about the numbers in the list as you keep applying the function?

Experiment with different starting values and different numbers of iterations. What do you notice?

# WRITE SOLUTION HERE

4. Working with pairs of lists#

4.1 Counting matching values in a pair of lists#

Write a function called count_matches that takes two lists of numbers as arguments and returns the number of times that the values at the same index in the two lists are equal.

For example:

count_matches([1, 2, 3, 4, 5], [1, 20, 3, -2, 5])

should return 3 because there are matching values at index 0, 2 and 4.

Note, your function should still work if the two lists are of different lengths.

# WRITE SOLUTION HERE
# TESTS
assert count_matches([1, 2, 3, 4, 5], [1, 2, 3, 4, 5]) == 5
assert count_matches([1, 2, 3, 4, 5], [1, 2, 3, 4, 6]) == 4
assert count_matches([1, 2, 3, 4, 5], [1, 2, 3]) == 3
assert count_matches([1, 2, 30, 4], [1, 2, 3, 4, 5, 6]) == 3
assert count_matches([], []) == 0
print("All tests passed")

4.2 Rotate list values by N#

Write a function called rotate_list that takes a list and returns a list of the same length but with the values in the original list shifted to the right by a given number of places. The values should rotate around the list, i.e. values that are shifted off the end should reappear at the start.

For example:

shift_list([1, 2, 3, 4, 5], 2)

should return [4, 5, 1, 2, 3].

Note, a negative value for the shift should rotate the values to the left.

Hint, this can be written in a couple of lines if you use list slicing. Understanding how -ve values work with list slicing is important for this problem. i.e., understand the meaning of my_list[-1:] and my_list[:-1].

# WRITE SOLUTION HERE
# TESTS
assert rotate_list([1, 2, 3, 4, 5], 1) == [5, 1, 2, 3, 4]
assert rotate_list([1, 2, 3, 4, 5], 2) == [4, 5, 1, 2, 3]
assert rotate_list([1, 2, 3, 4, 5], 7) == [4, 5, 1, 2, 3]
assert rotate_list([1, 2, 3, 4, 5], 0) == [1, 2, 3, 4, 5]
assert rotate_list([1, 2, 3, 4, 5], 5) == [1, 2, 3, 4, 5]
assert rotate_list([1, 2, 3, 4, 5], -1) == [2, 3, 4, 5, 1]
assert rotate_list([1, 2, 3, 4, 5], -11) == [2, 3, 4, 5, 1]
print("All tests passed")

4.3 Aligning two#

Write a function called align_lists that takes two lists and returns the right shift that should be applied to the second list to best align it with the first list. The alignment is scored by counting the number of matching values in the two lists. For example:

align_lists([1, 2, 3, 4, 5], [2, 0, 4, 5, 1])

should return 1 because the second list is best aligned when it is shifted one place to the right.

Hint, you can use the rotate_list and count_matches functions you wrote above to help you solve this problem.

# WRITE SOLUTION HERE
# TESTS
assert align_lists([1, 2, 3, 4, 5], [1, 2, 3, 4, 5]) == 0
assert align_lists([1, 2, 3, 4, 5], [2, 3, 4, 5, 1]) == 1
assert align_lists([2, 3, 4, 5, 1], [1, 2, 3, 4, 5]) == 4
assert align_lists([1, 2, 3, 4, 5], [2, 0, 4, 5, 1]) == 1
print("All tests passed")

DNA sequence alignment demo#

If you have written the functions correctly, the following gene sequence alignment demo should work.

DNA sequences can be represented by sequences of the symbols A, C, G and T representing the four bases that appear in DNA. The demo imagines that you have two snippets of DNA and wish to compare them by seeing how many matching bases they have. However, the two sequences are not aligned, i.e. the snippets don’t start at exactly the same position in the DNA sequence. The demo will align the sequences by shifting one of them to the right and then score the alignment by counting the number of matching bases. The alignment with the highest score is the best alignment and is used to compute the similarity between the two sequences, i.e. the percentage of bases that match.

❗ Note how the demo is passing strings to functions that expect lists. This works because in Python strings are represented as lists of characters. A string can be used in any place that expects a list.

seq1 = "GAATGCGGGGTAAAAAATGGCACTTAACCCTTCAAATGACGACCCTGCCTGAGCTGCCGCCGGAAGAGCGTCCGGCAGCT"
seq2 = "GGGTAAAAAAGGGCACTTAACCCTTCAGATGACGACCCTGCGTGAGCTGCCGCCAGAAGAGCGTCCGGCAGCTGGTGCGG"

match_score = 100*count_matches(seq1, seq2)/len(seq1)
shift = align_lists(seq1, seq2)
aligned_seq2 = rotate_list(seq2, shift)
aligned_match_score = 100*count_matches(seq1, aligned_seq2)/len(seq1)

print("Original sequences:")
print(seq1)
print(seq2)
print("These sequences have a match score of", match_score, "%")
print("\n")
print("After shifting the second sequence", shift, "positions:")
print(seq1)
print(aligned_seq2)
print("These sequences have a match score of", aligned_match_score, "%")

4.4 Multiplying pairs of values in two lists#

Write a function called multiply_lists that takes two lists of numbers as arguments and returns a new list with the product of the values in the two lists.

For example:

multiply_lists([1, 2, 3, 4, 5], [1, 2, 3, 0, 0])

should return [1, 4, 9, 0, 0].

If the lists have unequal lengths the returned list should be the same length as the shorter list.

# WRITE SOLUTION HERE
# TESTS
assert multiply_lists([1, 2, 3, 4, 5], [1, 2, 3, 4, 5]) == [1, 4, 9, 16, 25]
assert multiply_lists([1, 2, 3, 4, 5], [2, 2, 2]) == [2, 4, 6]
assert multiply_lists([1, 2, 3, 4, 5], [1, 2, 3, 0, 0]) == [1, 4, 9, 0, 0]
assert multiply_lists([2, 2, 2], [1, 2, 3, 4, 5]) == [2, 4, 6]
assert multiply_lists([1, 2, 3, 4, 5], []) == []
print("All tests passed")

4.5 Applying a function to pairs of values in two lists#

Write a function called apply_to_lists that takes two lists of numbers and a function as arguments and returns a new list with the function applied to the pairs of values in the two lists.

For example:

def add(x, y):
    return x + y

apply_to_lists([1, 2, 3, 4, 5], [1, 2, 3, 0, 0], add)

should return [2, 4, 6, 4, 5].

# WRITE SOLUTION HERE
# TESTS
assert apply_to_lists([1, 2, 3, 4, 5], [10, 20, 30, 40, 50], lambda x,y: x*y) == [10, 40, 90, 160, 250]
assert apply_to_lists([1, 2, 3, 4, 5], [10, 20, 30, 40, 50], lambda x,y: x+y) == [11, 22, 33, 44, 55]
print("All tests passed")   

The tests above are using lambda functions to define the function to be applied. Lambda functions are short functions that are defined inline and are convenient for this kind of problem. You can read about lambda functions here if you are interested.

Without using lambda functions, the above example would look like this:

def add(x, y):
    return x + y

def multiply(x, y):
    return x * y

assert apply_to_lists([1, 2, 3, 4, 5], [10, 20, 30, 40, 50], multiply) == [10, 40, 90, 160, 250]
assert apply_to_lists([1, 2, 3, 4, 5], [10, 20, 30, 40, 50], add) == [11, 22, 33, 44, 55]
print("All tests passed")

5. Working with sets#

5.1 Counting number of unique values in a list#

Write a function called count_unique that takes a list of numbers and returns the number of unique values in the list.

For example:

count_unique([1, 2, 3, 4, 5, 1, 2, 3, 4, 5])

should return 5 because there are five unique values in the list.

Hint: this problem can be solved trivially with a single line of code if you use a set.

# WRITE SOLUTION HERE
# TESTS
assert count_unique([1, 2, 3, 4, 5]) == 5
assert count_unique([1, 2, 3, 4, 5, 1, 2, 3]) == 5
assert count_unique([1, 2, 3, 4, 5, 1, 2, 3, 1, 2, 3]) == 5
assert count_unique([]) == 0
print("All tests passed")

5.2 Counting number of unique words in a text passage#

Write a function called get_unique_words that takes a string of text and returns the set of unique words in the text. The function should ignore case, i.e. ‘The’ and ‘the’ count as the same word and should be returned as ‘the’. Also it should ignore any punctuation in the string.

For example:

count_unique_words('The quick brown fox jumped over the lazy dog.')

should return {'the', 'quick', 'brown', 'fox', 'jumped', 'over', 'lazy', 'dog'} because there are eight unique words in the text.

Hint: You will want to use the split() function to split the text into words. You will also want to use the lower() function to convert all the words to lower case so that words that differ only in case are counted as the same word. You will also want to use the strip() function to remove punctuation from the words. If you import string, you can then use the string.punctuation variable to get a string containing all the punctuation characters.

# WRITE SOLUTION HERE
# TESTS
assert get_unique_words('The quick brown fox jumped over the lazy dog.') == {'the', 'quick', 'brown', 'fox', 'jumped', 'over', 'lazy', 'dog'}
assert get_unique_words('The very, very, very large dog barked.') == {'the', 'very', 'large', 'dog', 'barked'}
assert get_unique_words('The large dog --- that barked -- was very, very LARGE!') == {'the', 'large', 'dog', 'that', 'barked', 'was', 'very'}
assert get_unique_words('... @$! $^&&!! ?? !!') == set() # Empty set
assert get_unique_words('0 00 10 10 01 11 11 10') == {'0', '00', '01', '10', '11'}  # Numbers count as words
print("All tests passed")

5.3 Finding the set of words that are shared between two text passages#

Write a function called shared_words that takes two strings of text and returns a list of the words that are shared between the two texts.

For example:

shared_words('the quick brown fox jumped over the lazy dog', 'the lazy brown dog sat in the sun')

should return ['the', 'brown', 'dog'] because these are the words that are shared between the two texts.

# WRITE SOLUTION HERE
# TESTS
assert shared_words('The quick brown fox jumped over the lazy dog.', 'the lazy brown dog sat in the sun') == {'the', 'lazy', 'brown', 'dog'}
assert shared_words('These two strings', 'have no shared words') == set()
print("All tests passed")

5.4 Finding words that occur in one text passage but not another#

Write a function called non_shared_words that takes two strings of text and returns a list of the words that occur in the first text but not the second.

For example:

non_shared_words('the quick brown fox jumped over the lazy dog', 'the lazy brown dog sat in the sun')

should return {'quick', 'fox', 'jumped', 'over'} because these are the words that occur in the first text but not the second.

# WRITE SOLUTION HERE
# TESTS
assert non_shared_words('the quick brown fox jumped over the lazy dog', 'the lazy brown dog sat in the sun') == {'quick', 'fox', 'jumped', 'over'}
assert non_shared_words('1 2 3 4 5 6 7', '4 5 6 7 8 9 10') == {'1', '2', '3'}   
assert non_shared_words('4 5 6 7 8 9 10', '1 2 3 4 5 6 7') == {'8', '9', '10'}   
assert non_shared_words('1 2 3 4 5', '') == {'1', '2', '3', '4', '5'}
assert non_shared_words('1 2 3 4 5', '1 2 3 4 5') == set()
print("All tests passed")

6. Working with dictionaries#

6.1 Checking if a key is in a dictionary#

Write a function called has_key that takes a dictionary and a key as arguments and returns True if the key is in the dictionary and False otherwise.

For example:

has_key({'a': 1, 'b': 2, 'c': 3}, 'b')

should return True because the key 'b' is in the dictionary.

This is a trivial function that is just a single line of code. This is just an exercise. It wouldn’t be useful in a real program.

# WRITE SOLUTION HERE
# TESTS
assert has_key({'a': 1, 'b': 2, 'c': 3}, 'a') == True
assert has_key({'a': 1, 'b': 2, 'c': 3}, 'd') == False
print("All tests passed")

6.2 Counting occurrences of values in a list#

Write a function called count_occurrences that takes a list and returns a dictionary that maps each unique value in the list to the number of times it occurs in the list.

For example:

count_occurrences(['a', 'b', 'a', 'c', 'a', 'b', 'a', 'd'])

should return {'a': 4, 'b': 2, 'c': 1, 'd': 1} because 'a' occurs four times, 'b' occurs twice, 'c' and 'd' occur once.

# WRITE SOLUTION HERE
# TESTS
assert count_occurrences(['a', 'b', 'a', 'c', 'a', 'b', 'a', 'd']) == {'a': 4, 'b': 2, 'c': 1, 'd': 1}
assert count_occurrences(['a', 'a', 'a', 'a', 'a']) == {'a': 5}
assert count_occurrences(['a'] * 20 + ['b'] * 30 + ['c'] * 40) == {'a': 20, 'b': 30, 'c': 40}
print("All tests passed")

6.3 Implementing a cache#

Write a function called cache that takes a function as an argument and returns a new function that caches the results of the function calls. If the function is called again with the same arguments, the cached result is returned instead of calling the function again. The function should print a message indicating whether the result was returned from the cache or computed. For example:


def cache(func):
    """A function that takes a function as an argument and returns a new function that caches the results of the function calls. If the function is called again with the same arguments, the cached result is returned instead of calling the function again.

    For example:

    >>> def add(x, y):
    ...     print('called add')
    ...     return x + y
    >>> cached_add = cache(add)
    >>> cached_add(1, 2)
    called function
    3
    >>> cached_add(1, 2)
    retrieved from cache
    3
    >>> cached_add(2, 3)
    called function
    5
    >>> cached_add(2, 3)
    retrieved from cache
    5
    """
    pass

:warning: This is a difficult problem. Don’t worry if you can’t solve it. Some hints: a function can be defined inside a function and returned. Try writing it for a specifically for the ‘add’ function first. Then try to make it work for any function. If you get stuck just skip and go onto the next problem. Study the solution when it is posted.

# WRITE SOLUTION HERE
# TESTS
cached_add = cache(lambda x, y: x + y)
assert cached_add(1, 2) == 3  # will call function
assert cached_add(1, 2) == 3  # will retrieve from cache
assert cached_add(2, 3) == 5  # will call function
assert cached_add(2, 3) == 5  # retrieve from cache
print("All tests passed")

6.4 Map two lists into a dictionary#

Write a function called make_dictionary that takes two lists of equal length and returns a dictionary that maps the values in the first list to the values in the second list.

For example:

make_dictionary(['a', 'b', 'c'], [1, 2, 3])

should return {'a': 1, 'b': 2, 'c': 3}.

# WRITE SOLUTION HERE
# TESTS
assert make_dictionary(['a', 'b', 'c'], [1, 2, 3]) == {'a': 1, 'b': 2, 'c': 3}
print("All tests passed")

6.5 Merging a pair of dictionaries#

Write a function that takes a pair of dictionaries for which all the values are numeric and returns a new dictionary that contains the sum of the values for each key.

For example:

merge_dictionaries({'a': 1, 'b': 2, 'c': 3}, {'a': 4, 'b': 5, 'd': 6})

should return {'a': 5, 'b': 7, 'c': 3, 'd': 6}.

# WRITE SOLUTION HERE
# TESTS
dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 5, 'c': 3}
assert merge_dictionaries(dict1, dict2) == {'a': 1, 'b': 7, 'c': 3}
assert dict1 == {'a': 1, 'b': 2}  # Make sure original dictionaries are not modified
assert dict2 == {'b': 5, 'c': 3}
print("All tests passed")

6.6 Merging a list of dictionaries#

Write a function called merge_list_of_dictionaries that takes a list of dictionaries for which all the values are numeric and returns a new dictionary that contains the sum of the values for each key.

For example:

merge_dictionaries([{'a': 1, 'b': 2, 'c': 3}, {'a': 4, 'b': 5, 'd': 6}, {'a': 7, 'c': 8, 'e': 9}])

should return {'a': 12, 'b': 7, 'c': 11, 'd': 6, 'e': 9}.

You can use your merge_dictionaries function from the previous problem to help you solve this problem.

# WRITE SOLUTION HERE
# TESTS
assert merge_list_of_dictionaries([{'a': 1, 'b': 2, 'c': 3}, {'a': 4, 'b': 5, 'd': 6}, {'a': 7, 'c': 8, 'e': 9}]) == {'a': 12, 'b': 7, 'c': 11, 'd': 6, 'e': 9}
print("All tests passed")

Copyright © 2023, 2024 Jon Barker, University of Sheffield. All rights reserved.