What is the most Pythonic way to count word frequencies in a string, and what does Counter return for missing keys?
collections.Counter is the standard tool: it accepts any iterable and returns a dict-like object with counts. For a missing key it returns 0 rather than raising KeyError, which makes downstream arithmetic safe without extra guards.
How to think about it
This is a classic frequency-counting problem. The interesting part isn’t just getting the counts — it’s knowing the full Counter API: missing keys, merging counters, getting top-k, and when to reach for the manual dict.get fallback.
What’s really being tested
Interviewers want to see you know Counter exists and can explain why it’s better than a manual loop (cleaner, richer API, same O(n) complexity). They’ll often follow up with “what if you don’t have collections?” — so know the dict.get fallback too.
Step 1 — The Pythonic way with Counter
Counter accepts any iterable. Pass it a list of words and you’re done. The resulting object behaves like a dict with one important difference: accessing a missing key returns 0 instead of raising KeyError.
Step 2 — The top-k query
most_common(k) uses a heap internally — it’s O(n log k), which is significantly faster than sorting the whole dict when k is small.
Step 3 — The manual fallback
When Counter isn’t available or you want to show you understand what’s happening underneath, dict.get(key, 0) + 1 achieves the same thing.
The key insight — why Counter beats a manual loop
Counter is O(n) just like a manual loop, but it comes with most_common, arithmetic operators (+, -, &, |), and the zero-default that makes downstream math safe. There’s no reason to write the loop manually in production code.