Top N Keys
A medium Python interview practice problem on DataDriven. Write the Python and run it against test cases, with instant feedback.
- Domain
- Python
- Difficulty
- medium
- Seniority
- L3
Problem
We're profiling API endpoints, each mapped to a numeric score, and we want the heaviest hitters. Given that map and a count n, return the top n endpoints by score, biggest first; when two scores tie, order those keys alphabetically.
Most of them do not matter. The few that do stand out.
Example 1
Input:
data = {"endpoint_a":1200,"endpoint_b":3400,"endpoint_c":800,"endpoint_d":2100}, n = 2Output:
["endpoint_b","endpoint_d"]
Example 2
Input:
data = {"cache":50,"queue":90,"worker":50}, n = 2Output:
["queue","cache"]
Worked solution and explanation
The problem under the costume
This is a two-directional sort hiding inside a 'top scorers' ask. The real question: can you order by score descending and, when scores collide, by key ascending, resolved in one pass? Anyone can call sorted(). The trap is reaching for sorted(data, key=data.get, reverse=True): reverse=True flips the whole comparison, so tied keys come back in dict insertion order, not alphabetical. Feed it {'cache': 50, 'worker': 50} and you get whichever landed in the dict first. That is non-deterministic across inputs and quietly fails every tie case.
The one trick
Walk it
Step 1: Build the ordering key
For each key, the sort key is (-data[k], k). The negated score dominates, so higher scores sort first; the raw key breaks ties in ascending alphabetical order. One key function, one pass.
Step 2: Slice the top n
ordered[:n] takes the first n. When n is larger than the dict, the slice simply returns everything, so the 'fewer than n keys' case needs no guard.
def top_n_keys(data: dict, n: int) -> list:
ordered = sorted(data, key=lambda k: (-data[k], k))
return ordered[:n]- sorted(..., reverse=True)
- Flips the comparison for one field only. Values sort descending, but tied keys keep dict insertion order, so
{'cache': 50, 'worker': 50}is non-deterministic and fails the tie tests. - sorted(..., key=(-value, key))
- One tuple encodes both directions:
-valuedescends,keyascends. Ties always resolve alphabetically, deterministically, in a single sort.
Common follow-up questions
- What if a tie straddles the nth position? (Tests whether to include all tied keys or strictly cap at n.)
- When does heapq.nlargest outperform a full sort? (Tests understanding that a heap wins when n is much smaller than the total count.)
- How would you keep the top n if scores arrived as a stream? (Tests maintaining a bounded min-heap of size n as new entries stream in.)