Python sorted() with key: Rank a Dictionary by Value
To rank a dictionary by value in Python, pass the dictionary to sorted() with key= set to its get method. You get the keys back, ordered by their values.
Use it to turn a dictionary of scores or counts into a leaderboard. Read Sorting and Dictionaries first; this lesson assumes sorted(), reverse=True and key=len.
Rank keys by their values
Looping over a dictionary gives its keys. scores.get is a function: give it a name and it returns that name's score. So sorted() compares scores but returns names.
scores = {"Ada": 7, "Sam": 9, "Lee": 4}
print(sorted(scores))
print(sorted(scores, key=scores.get, reverse=True))
The first line sorts the names alphabetically: ['Ada', 'Lee', 'Sam']. The second ranks them by score: ['Sam', 'Ada', 'Lee']. Write scores.get with no brackets. scores.get("Ada") would be one number, not a function.
Ties keep insertion order
Python's sort is stable: items with equal keys keep their original order. That holds with reverse=True too. For a dictionary, the original order is the order the keys were added.
scores = {"Ada": 7, "Sam": 9, "Lee": 7}
print(sorted(scores, key=scores.get, reverse=True))
This prints ['Sam', 'Ada', 'Lee']. Ada and Lee both have 7, and Ada was added first. Stability does not sort ties alphabetically. If ties must break by name, sort by name first, then by score: the second sort keeps the first sort's order among equal scores.
scores = {"Sam": 7, "Ada": 7, "Lee": 9}
by_name = sorted(scores)
print(sorted(by_name, key=scores.get, reverse=True))
This prints ['Lee', 'Ada', 'Sam']: highest score first, ties in alphabetical order.
Keep only the top few
A slice copies part of a list: ranking[:2] takes the items from the start up to, but not including, position 2. A slice past the end just gives the whole list. List slicing covers slices in full.
scores = {"Ada": 7, "Sam": 9, "Lee": 4, "Mia": 8}
ranking = sorted(scores, key=scores.get, reverse=True)
print(ranking[:2])
print(ranking[:10])
This prints ['Sam', 'Mia'], then all four names. An empty dictionary gives [].
See also: List methods, Lambda functions.
Your turn
counts maps words to how often they appear. Print the two most common words, most common first. pear and fig tie, so the one added first wins.
counts = {"plum": 2, "pear": 5, "fig": 5, "kiwi": 1}
# add two lines: rank the words by count, biggest first, then print the first two
Expected output
['pear', 'fig']