Contents

Dict drills

Drills to practice working with Python dictionaries.

Built-in dict

Create a dictionary, d, from the two lists below using the dict() constructor.

1
2
keys = ["a", "b", "c"]
values = range(3)
1
d = dict(zip(keys, values))

Recreate the same dictionary using dictionary comprehension and check that the result is identical to d.

1
2
dd = {key: value for key, value in zip(keys, values)}
dd == d

What does the below return and why?

1
{key: value for key in keys for value in values}

It returns 2 as the value for every key because for each key it iterates through all the values and returns the last one.

Return a list of all dictionary keys.

1
list(d)

Return the number of items in d.

1
len(d)

Return the value for key b in two different ways.

1
d["b"]
1
d.get("b")

Replace the above value with 5.

1
d["b"] = 5

Remove the entry c.

1
del d["c"]

Check that c is no longer present.

1
"c" not in d

Create a shallow copy, dd, of d.

1
dd = d.copy()

Try to return the value for the non-existend key x and intead return default.

1
d.get("x", "default")

Return a view of all key-value pairs.

1
d.items()

Return a view of all keys.

1
d.keys()

Return a view of all values.

1
d.values()

Remove key a and return its value, ensuring that if a isn’t in d, default is returned.

1
d.pop("a", "default")

Add keys m and n with values 10 and 11 to the dict.

1
2
d["m"] = 10
d["n"] = 11

Remove the last added key-value pair from the dict and return it.

1
d.popitem()

Return a reversed iterator over the keys and use it to print the values in reverse order.

1
2
for i in reversed(d):
    print(d[i])

Add key z to the dictionary initialising it with a default value of 0.

1
d.setdefault("z", 0)

Print the dictionary.

1
d

Check equality of d.values() with itself. What do you get and why?

It’s False, like all comparisons of view objects.

Delete all elements from the dictionary.

1
2
d.clear()
d

Create dictionaries m and n with keys from the string below, and with all values initialised as 1 and 2, repectively.

1
2
keys_m = "abcd"
keys_n = "cdef"
1
2
m = dict.fromkeys(keys_m, 1)
n = dict.fromkeys(keys_n, 2)

Create a new dict, o, with the combined keys of m and n, with the keys of the former taking precedent in the case of duplicate keys.

1
o = n | m

Update the values in n with those of m in place.

1
n.update(m)

Now update m with n using a different method.

1
m |= n

Counter

Create a dictionary d that stores the number of occurrences for each item in items.

1
items = "aabbcdeaabdd"
1
2
3
from collections import Counter

d = Counter(items)

Use d to produce a sorted version of items.

1
list(d.elements())

Find the two most common element in d and their counts.

1
d.most_common(2)

Find the three least common elements in d (in ascending order of frequency) and their counts.

1
d.most_common()[:-4:-1]

Add the counts of more_items to d. How does the method to be used compare to when called on a regular dictionary?

1
more_items = "aabcxxyzz"
1
d.update(more_items)

Based on the below two counters, create a new counter containing the minimum of all counts (with zero counts deleted from the dict).

1
2
a = Counter("aab")
b = Counter("bbc")
1
a & b

Now create one that contains the maximum of all counts.

1
a | b

Drop all items with negative counts from counter a below and explain what’s going on.

1
2
a = Counter({"a": 3, "b": -4})
a
Counter({'a': 3, 'b': -4})
1
+a

There are two things going on here: First, mathematical operations on counters drop items with negative counts (counters are built for counting positive things), and, second, unary operations +a or -a are shorthand for adding to or subtracting from an empty counter.

Ordered dict

Since Python 3.7, dict has been declared to maintain the order of keys as they are encountered. Hence, the use of OrderedDict is more limited (see here for a good discussion on when you might still use it), and Counter inherits the new behaviour as it is a dict subclass 💥.

Topics

Setting default values

Create a dict d from the below items, concatenating the list values for duplicate keys.

1
items = [("a", [1, 2]), ("b", [3, 4]), ("a", [3, 4]), ("c", [5])]

First, what happens if we call dict(items)?

The first set of values for a get overwritten by the second set of values.

Now, create d using the built-in dict.

1
2
3
4
d = {}
for key, value in items:
    d.setdefault(key, []).extend(value)
d

Do the same but in a different way.

1
2
3
4
5
6
d = {}
for key, value in items:
    if key not in d:
        d[key] = []
    d[key].extend(value)
d

Now do the same using the collections module.

1
2
3
4
5
6
from collections import defaultdict

d = defaultdict(list)
for key, data in items:
    d[key].extend(data)
d

Now, using any additional module you like, create d again but this time with values ([items], occurrences), where the first element is the value items as before, and the second element is a count for the number of times the key occurres in items (e.g. for key a we want ([1, 2, 3, 4], 2).)

1
2
3
4
5
d = collections.defaultdict(lambda: [[], 0])
for key, value in items:
    d[key][0].extend(value)
    d[key][1] += 1
d

Create a greeting function that takes a user ID as input and returns Hi name if the user ID has an entry in name_for_userid and Hi there otherwise.

1
2
3
4
5
name_for_userid = {
    382: "Alice",
    590: "Bob",
    951: "Dilbert",
}
1
2
def greeting(user_id):
    return "Hi {}".format(name_for_userid.get(user_id, "there"))

Setting default values in nested dictionaries

From Khuyen Tran

Get a list of the taste attribute for each fruit in list below, substituting unknown for fruits with no taste information.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
fruits = [
    {
        'name': 'apple',
        'attr': {'colour': 'red', 'taste': 'sweet'},
    },
    {
        'name': 'orange',
        'attr': {'colour': 'orange'},
    },
    {
        'name': 'banana',
    },
]

Complete the task without using any dictionary methods.

1
2
3
4
[fruit['attr']['taste']
 if 'attr' in fruit and 'taste' in fruit['attr']
 else 'unknown'
 for fruit in fruits]

Complete the task more elegantly than above.

1
2
[fruit.get('attr', {}).get('taste', 'unknown')
 for fruit in fruits]

Calculating with dics

Based on recipe 1.8 in the Python Cookbook

1
prices = {"ACME": 45.23, "AAPL": 612.78, "IBM": 205.55, "HPQ": 37.20, "FB": 10.75}

Return the name of the stock with the highest price.

1
max(prices, key=lambda x: prices[x])

Return the key-value pair for the stock with the lowest price.

1
min(prices.items(), key=lambda x: x[1])

Return the items in decreasing order of price.

1
sorted(prices.items(), key=lambda x: x[1], reverse=True)

Mapping dict values to list items

Create a list containing the dict values of the elements in a in two different ways.

1
2
d = {1: 'a', 2: 'b', 3: 'c'}
a = [1, 2, 3, 1, 2]
1
list(map(d.get, a))
1
[d.get(item) for item in a]

Now do the same for the new list a, and use 99 as the value for items that aren’t in d. Use again two different ways.

1
a = [1, 2, 3, 1, 100]
1
list(map(lambda x: d.get(x, 99), a))
1
[d.get(item, 99) for item in a]