Start learning free

LESSON 265 OF 673 · TUPLES, SORTING & BUILT-INS

Leaderboard in Python: Sorting Tuples by Two Rules

Practice Read the full explanation

You get a list of players, players. Each player is a pair: a name and a score, like ("Ava", 30).

Return the names, from the highest score to the lowest.

Players with the same score go in alphabetical order of their names.

The starter code shows how your language holds a pair.

 

Example 1:

Input: players = [("Ava", 30), ("Ben", 25), ("Cy", 40)]
Output: ["Cy", "Ava", "Ben"]
Explanation: Cy has the most points, 40.
Then come Ava with 30 and Ben with 25.

Example 2:

Input: players = [("Mia", 50), ("Leo", 70), ("Ava", 50)]
Output: ["Leo", "Ava", "Mia"]
Explanation: Leo leads with 70.
Ava and Mia both have 50.
Ava comes first from A to Z.

Example 3:

Input: players = [("Zoe", 0)]
Output: ["Zoe"]
Explanation: Zoe is the only player.

 

Constraints:

  • players has 1 to 100 players.
  • Every score is a whole number from 0 to 1000.
  • Each name is a capital letter followed by lowercase letters, like "Ava".
  • No two players have the same name.
STEP 1 OF 5
    Ctrl + Enter to check

    PYTHON · TUPLES, SORTING & BUILT-INS

    Leaderboard in Python, explained

    Problem overview

    The method leaderboard gets players, a list of pairs like ("Ava", 30): a name and a score. It returns only the names, from the highest score to the lowest. Players with the same score go in alphabetical order of their names. Names are all different.

    For [("Mia", 50), ("Leo", 70), ("Ava", 50)] the answer is ["Leo", "Ava", "Mia"]: Leo leads with 70, and Ava comes before Mia among the two 50s.

    Approach

    There are two rules in opposite directions: scores go high to low, names go A to Z. A single sort key handles both. The key (-player[1], player[0]) puts the negated score first. A bigger score becomes a smaller negative number, which sorts earlier. When two scores tie, Python compares the next part of the tuple, the name, in the usual A to Z order.

    Using reverse=True instead would flip both rules and put tied names in Z to A order. For the example above, reverse=True with the score alone gives Leo, Mia, Ava, which is wrong.

    For the second example, the keys are these:

    playerkey
    ("Mia", 50)(-50, 'Mia')
    ("Leo", 70)(-70, 'Leo')
    ("Ava", 50)(-50, 'Ava')

    -70 is the smallest, so Leo comes first. The two -50 keys tie on the first part, so 'Ava' and 'Mia' decide, and Ava goes first.

    Step by step

    1. Build ordered: players sorted with key returning (-player[1], player[0]). Here player[1] is the score.
    2. Start an empty list names.
    3. Loop over ordered, unpacking each pair into name and score.
    4. Append name to names.
    5. After the loop, return names.

    The solution in Python

    class Solution:
        def leaderboard(self, players: List[Tuple[str, int]]) -> List[str]:
            ordered = sorted(players, key=lambda player: (-player[1], player[0]))
            names = []
            for name, score in ordered:
                names.append(name)
            return names
    

    After sorting, ordered is a list of pairs; for the example it is [('Leo', 70), ('Ava', 50), ('Mia', 50)]. The loop unpacks each pair and keeps only the name. score is unused, which is fine.

    Testing

    [("Ava", 30), ("Ben", 25), ("Cy", 40)]   ->  ['Cy', 'Ava', 'Ben']
    [("Mia", 50), ("Leo", 70), ("Ava", 50)]  ->  ['Leo', 'Ava', 'Mia']
    [("Zoe", 0)]                             ->  ['Zoe']
    

    Why negating works

    Sorting ascending by -score is the same as sorting descending by score, as long as the score is a number. That is why the trick fits this lesson and not the names: a string can't be negated, and -"Mia" raises a TypeError. When only one part of the key is a number, you flip that part and leave the text alone.

    Another way to finish is a list comprehension: [name for name, score in ordered] gives the same names as the loop, in one line.

    Edge cases

    One player gives a list with that one name. A score of 0 works like any other, since -0 is just 0. Names are all different, so two players never tie on both parts of the key, and the order is always fully decided. The list comes out as long as the input, with every name once.

    A key on the whole pair

    Without a key, Python sorts pairs by name first and then by score, which is the wrong priority here. The key function is what puts the score first, and the minus sign is what turns "low to high" into "high to low".

    Common mistakes

    • Forgetting the minus sign, which sorts the lowest score first.
    • Negating the name: you can't put - before a string.
    • Returning ordered instead of names: the result holds only names.
    Keep going with Python500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free