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 text, a raw text field pulled from our event logs, return a dict mapping each word to how many times it appears. The spacing in these fields is uneven: words may be separated by doubled spaces or tabs, and the field may be padded at either end. Words count exactly as written, so differently cased spellings stay separate.

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

Example 1

Input:

text = "click view click submit view view"

Output:

{"click":2,"view":3,"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 and count how many times each shows up. Almost everyone gets the counting right. What separates people is one keystroke: text.split() with no argument versus text.split(' ') with a literal space. The two agree 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 the dict with an empty-string key that carries a real count. The output is wrong in a way that survives casual eyeballing.

How you get there

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

Uneven spacing is the tell in the prompt. No-argument split() collapses runs of spaces, tabs and newlines and strips both ends, so it never manufactures empty tokens. Hardcode split(' ') and you are betting the input is perfectly single-spaced, which real text never is.

Step 2: Tally in one pass

Feed the tokens straight into collections.Counter. It walks them once and increments in C. A hand-rolled counts[word] = counts.get(word, 0) + 1 loop is just as correct, but Counter is the idiom a reviewer expects, and it brings most_common() for the inevitable follow-up.

Step 3: Hand back a plain dict

The signature promises -> dict. Counter is a dict subclass, but wrapping it in dict() matches the contract exactly and won't surprise a caller that checks the concrete type. Empty input needs no special case: ''.split() is [], so the result 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(' ') gives ['', '', 'the', '', 'the', 'cat', '']. The tally now carries a '' key with count 3 next to 'the' with count 2: a junk key that passes a quick glance.
`split()`: correct
' the the cat '.split() gives ['the', 'the', 'cat'], so the tally is {'the': 2, 'cat': 1}. Runs collapse, ends trim, and no empty token ever appears.

Common follow-up questions