...

/

Solution Review: Count with Dictionary

Solution Review: Count with Dictionary

The solution to the 'Count with Dictionary' challenge.

We'll cover the following...
Python 3.10.4
from collections import defaultdict
from collections import OrderedDict
def count_letters(message):
d = defaultdict(int) # Making dictionary with int
for letter in message:
d[letter] += 1 # Adding 1 with every repetition
# Sorting on the basis of values
return 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 original dict order. 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.


Ask