The Ranked Dict
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
- Ripple
Problem
Build the leaderboard from scores, our dict of player names to points, with the highest score first. Points can be any number, negatives and fractions included, and an empty scores simply means an empty board.
Values deserve order too.
Example
Input:
scores = {"bob":87,"dave":70,"alice":95,"carol":95}Output:
[["alice",95],["carol",95],["bob",87],["dave",70]]
Worked solution and explanation
What this really is
This is a two-level sort dressed up as a leaderboard. Everyone gets "highest score first" right. What separates candidates is the second level: players on the same score have to come out in a fixed order, and the only order the data can justify is the name. Sort on the score alone and Python's stable sort quietly keeps tied players in whatever order the dict handed them over, so 'carol' beats 'alice' just because she arrived first.
There is a second, quieter trap. Plenty of candidates sort the entries and pour them back into a dict, because dicts remember insertion order. That works for display, but a dict compares equal to the same mapping in any order, so nothing downstream can tell your board from an unsorted one. The board is a sequence, so return a sequence.
Building the board
Step 1: Take the entries out of the dict
Call scores.items() and wrap it in list(...). You now hold name-score pairs you can reorder freely, and the caller's dict is never touched.
Step 2: Encode both rules in one key
Ask what the sort compares. The tuple (-entry[1], entry[0]) compares the negated score first, so bigger scores sort earlier, and only when scores match does it fall through to the name, which sorts A to Z.
Step 3: Sort the list and hand it back
standings.sort(...) reorders the list you just built and you return it as is. Each pair comes back as [name, score], matching the visible example.
def rank_players(scores):
standings = list(scores.items())
# Higher score first; equal scores fall back to the name, A to Z.
standings.sort(key=lambda entry: (-entry[1], entry[0]))
return standingsNegating the score flips its direction while the name keeps ascending order.
- Score only, descending
sort(key=lambda entry: entry[1], reverse=True)is stable, so 'carol' (listed first) stays ahead of 'alice'. The board depends on input order.- Score, then name
sort(key=lambda entry: (-entry[1], entry[0]))puts 'alice' ahead of 'carol' every time, whatever order the dict arrived in.
Common follow-up questions
- What if only the top 3 players should appear on the board? (Slicing after the sort versus a bounded heap with the same key.)
- How would you give tied players the same position number, with no gaps after a tie? (Tests carrying state across the sorted list rather than using the index.)
- What changes if names should sort case-insensitively, so 'alice' and 'Alice' sit together? (Tests normalizing inside the key without altering the returned names.)