The Top Reviewer

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

Problem

An analyst noticed the most-reviewed badge flips between restaurants with the same review count depending on how the export was loaded. Given restaurants, a dict of restaurant names to their review lists, return the name with the most reviews so the badge lands on the same place every time.

One restaurant receives the most feedback - which one?

Example 1

Input:

restaurants = {"Sushi Spot":["loved it","will return"],"Burger Barn":["amazing"],"Pizza Palace":["great","ok","meh"]}

Output:

"Pizza Palace"

Example 2

Input:

restaurants = {"Bella Roma":["fresh","cozy"],"Dosa House":["spicy"],"Cedar Kitchen":["tasty","warm"],"Elm Street Cafe":["quiet","bright"]}

Output:

"Bella Roma"

Worked solution and explanation

The tie is the whole question

This is an argmax with a tiebreak that points the other way, dressed up as a review badge. Finding the restaurant with the most reviews is one line anyone writes. What separates candidates is the tie: most reviews wants a maximum, alphabetically first wants a minimum, and the two pull in opposite directions. Let the dict's insertion order settle it and the badge flips every time the export is reloaded in a different order, which is exactly the bug the analyst reported.

Look at the second example. Cedar Kitchen, Bella Roma and Elm Street Cafe all have two reviews. Cedar arrives first, Elm arrives last, and the expected answer is Bella Roma, sitting in between. Arrival order is not the rule, and neither is the alphabetically last name.

Step 1: Count each restaurant with len()

Walk restaurants.items(), unpack each entry into name and reviews, and record (name, review_count) in scored. An empty list is simply zero, so Empty Eats never needs a special case and never beats a restaurant that has any reviews.

Step 2: Turn both criteria into one direction

Negating the count flips 'most' into 'smallest', which now points the same way as 'alphabetically first'. The key (-pair[1], pair[0]) makes a single min ask for the most reviews and, among equals, the first name.

Step 3: Unpack the winner

min over scored returns a (name, review_count) pair. Unpack it and return the name; the count was only needed to decide the order.

Count once, compare both criteria in one key
def most_reviewed(restaurants: dict) -> str:
    scored = []
    for name, reviews in restaurants.items():
        review_count = len(reviews)
        scored.append((name, review_count))

    # Most reviews first; among equal counts, the alphabetically first name.
    winner, _count = min(scored, key=lambda pair: (-pair[1], pair[0]))
    return winner

min with a negated count maximizes reviews and minimizes the name in the same comparison.

Uniform max key
max(scored, key=lambda pair: (pair[1], pair[0])) maximizes the name too, so on the tie it returns Elm Street Cafe, the alphabetically last.
Mixed-direction key
min(scored, key=lambda pair: (-pair[1], pair[0])) negates only the count, so the tie resolves to Bella Roma.

Common follow-up questions