Everything Said Twice

An easy Python interview practice problem on DataDriven. Write the Python and run it against test cases, with instant feedback.

Domain
Python
Difficulty
easy
Seniority
L3
Asked in
Tata Consultancy Services

Problem

Given a string of words separated by whitespace, return a dict mapping each distinct word to the number of times it appears.

Every word leaves a mark. Count who keeps coming back.

Example 1

Input:

text = "click view click submit view view"

Output:

{"view":3,"click":2,"submit":1}

Example 2

Input:

text = "hello"

Output:

{"hello":1}

Worked solution and explanation

What this is really testing

Strip the costume and this is a tokenize-and-tally: chop a string into words, count how many times each shows up. Everyone gets the counting part right; almost nobody trips on the dict accumulation. The thing that actually separates people is one keystroke: whether you call text.split() with no argument or text.split(' ') with a literal space. They look identical on the happy path 'a b c' and diverge the instant the input has a double space, a tab, or a leading blank. Pick the wrong one and you silently seed your dict with an empty-string key that carries a real count, and your output is wrong in a way that passes casual eyeballing.

How you get there

Step 1: Split on whitespace, not on a space character

The spec says 'separated by whitespace' and that phrasing is the tell. No-arg split() collapses runs of spaces, tabs, and newlines, and strips leading/trailing whitespace, so you never manufacture empty tokens. The moment you hardcode split(' ') you are counting on the input being perfectly single-spaced, which real text never is.

Step 2: Tally in one pass

Feed the token list straight into collections.Counter. It walks the tokens once, O(n), and increments in C. You could hand-roll d[w] = d.get(w, 0) + 1 and it would be correct, but Counter is the idiom a reviewer expects here and it comes with .most_common() for the inevitable follow-up.

Step 3: Hand back a plain dict

The signature promises -> dict. Counter IS a dict subclass and compares equal, so tests usually pass either way, but wrapping in dict() matches the contract exactly and won't surprise a caller that inspects the concrete type. Empty input needs no special case: ''.split() is [], Counter([]) is empty, dict() is {}.

Counter over whitespace-split tokens
from collections import Counter

def word_counts(text: str) -> dict:
    return dict(Counter(text.split()))

One pass to split, one pass to count.

split(' ') — the trap
' the the cat '.split(' ') -> ['', '', 'the', '', 'the', 'cat', ''] . Counter now has a '' key with count 3 and 'the' count 2. The output silently carries a junk key and passes a quick glance.
split() — correct
' the the cat '.split() -> ['the', 'the', 'cat'] . Counter is {'the': 2, 'cat': 1} . Runs collapse, ends trim, no empty tokens, ever.

Common follow-up questions