Relying on Counter is actually not the only way to track frequencies; we already know that Counter is a special kind of dictionary, so reproducing the Counter behavior should be quite straightforward.
Probably every one of us came up with a dictionary in this form:
counts = dict(hello=0, world=0, nice=0, day=0)
Whenever we face a new occurrence of hello, world, nice, or day, we increment the associated value in the dictionary and call it a day:
for word in 'hello world this is a very nice day'.split():
if word in counts:
counts[word] += 1
By relying on dict.get, we can also easily adapt it to count any word, not just those we could foresee:
for word in 'hello world this is a very nice day'.split():
counts[word] = counts.get(word, 0) + 1
But the standard library actually provides a very flexible tool that we can use to improve this code even further, collections.defaultdict.
defaultdict is a plain dictionary that won't throw KeyError for any missing value, but will call a function we can provide to generate the missing value.
So, something such as defaultdict(int) will create a dictionary that provides 0 for any key that it doesn't have, which is very convenient for our counting purpose:
from collections import defaultdict
counts = defaultdict(int)
for word in 'hello world this is a very nice day'.split():
counts[word] += 1
The result will be exactly what we expect:
defaultdict(<class 'int'>, {'day': 1, 'is': 1, 'a': 1, 'very': 1, 'world': 1, 'this': 1, 'nice': 1, 'hello': 1})
As for each word, the first time we face it, we will call int to get the starting value and then add 1 to it. As int gives 0 when called without any argument, that achieves what we want.
While this roughly solves our problem, it's far from being a complete solution for counting—we track frequencies, but on everything else, we are on our own. What if we want to know the most frequent entry in our bag of words?
The convenience of Counter is based on the set of additional features specialized for counting that it provides; it's not just a dictionary with a default numeric value, it's a class specialized in keeping track of frequencies and providing convenient ways to access them.