Solution Review: Count with Dictionary
The solution to the 'Count with Dictionary' challenge.
We'll cover the following...
from collections import defaultdictfrom collections import OrderedDictdef count_letters(message):d = defaultdict(int) # Making dictionary with intfor letter in message:d[letter] += 1 # Adding 1 with every repetition# Sorting on the basis of valuesreturn OrderedDict(sorted(d.items(), key=lambda t: (t[1], t[0])))print(count_letters('Welcome to Educative'))
Explanation
In the code above, we first import defaultdict and OrderedDict to solve the problem. Now, look at the header of the count_letters function at line 4. It takes message as a parameter containing the string that we want to count the letters of. The only trick here was to know the value of default_factory when making a defaultdict object. Setting default_factory as int makes it useful to count values just like with a Counter object.
So, at line 6, we make a dictionary-like object d, setting default_factory as int. Next, we have to traverse the message. Each letter in message can be used as a key( see line 7). The question is how to add values in d. When a letter is first encountered, it is missing from d, so the default_factory function calls int() to supply a default count of zero. The increment operation then builds up the count for each letter (see line 8).
We are not done yet. The defaultdict is an unordered container. So, we need to sort it, yet maintain that sorted order. According to the problem, we have to sort in on the basis of values. Look at line 11. We make an OrderedDict dictionary. We pass the sorted() function in the constructor, taking:
- The
d.items()that needs to be sorted. - The criteria of sorting, i.e., according to values:
key = lambda t:(t[1], t[0]).
The
key=lambda t: t[1]won’t work, as expected. For example, if two letters have the same frequency, their relative order is arbitrary because Python’s sort is stable, but it depends on the originaldictorder. That’s why the output can look “random” between runs.Using a tuple sort key (frequency, letter) instead of frequency alone will give consistent results.
We are returning the dictionary object created by the OrderedDict constructor. Lastly, we are calling the function count_letters with ‘Welcome to Educative’ as a message at line 13, and printing the required result.