Skip to content

Intermediate · Working with data · topic 29 of 50 · 20 min

Sorting with key

Explanation

sorted() gives you a new sorted list, while list.sort() sorts the list itself and returns None. The key argument tells Python what to compare, such as key=len or key=lambda s: s[1]. Add reverse=True for biggest first, and use a tuple as the key to sort by two things at once.

sorted() versus list.sort()

python
marks = [72, 45, 90, 61]
print(sorted(marks))          # new list
print(marks)                  # unchanged
marks.sort(reverse=True)      # sorts marks itself
print(marks)
sorted works on any collection; .sort() only exists on lists.
Careful: list.sort() returns None. Writing marks = marks.sort() throws your list away and leaves marks as None. Use marks.sort() on its own line, or marks = sorted(marks).

Sorting with key

key is a function that Python calls on every item. It sorts the items by the values that function returns, but it moves the original items. key=len sorts by length; key=str.lower sorts without caring about capital letters.

python
names = ["meena", "Asha", "Ravi", "bhavya"]
print(sorted(names))
print(sorted(names, key=str.lower))
print(sorted(names, key=len))
Without a key, every capital letter comes before every small letter.
Think of it like this: Think of a PT teacher lining up a class. "Line up by height" is the key: the teacher compares heights, but it is the students who move. Change the key to "by roll number" and the same students line up differently.
python
students = [("Asha", 82), ("Ravi", 67), ("Meena", 91)]
print(sorted(students, key=lambda s: s[1]))
print(sorted(students, key=lambda s: s[1], reverse=True))
lambda s: s[1] means "compare by the marks part of each pair".

Sorting a dict by its values

python
sales = {"tea": 120, "coffee": 45, "lassi": 80}
ranked = sorted(sales.items(), key=lambda kv: kv[1], reverse=True)
print(ranked)
print(dict(ranked))
print(sorted(sales, key=sales.get))
sales.items() gives (key, value) pairs; sorting a dict directly gives only its keys.

Two keys at once with a tuple

python
students = [("Ravi", 82), ("Asha", 91), ("Meena", 82)]
merit = sorted(students, key=lambda s: (-s[1], s[0]))
print(merit)
Highest marks first; equal marks in A to Z name order.
Tip: Tuples are compared item by item, so (marks, name) sorts by marks and uses name only for ties. To make only the number go from high to low, negate it: -s[1]. This works for numbers, not for strings.

operator.itemgetter

python
from operator import itemgetter
students = [("Asha", 82), ("Ravi", 67)]
print(sorted(students, key=itemgetter(1)))
products = [{"name": "Soap", "price": 40}, {"name": "Oil", "price": 180}]
print([p["name"] for p in sorted(products, key=itemgetter("price"))])
itemgetter(1) is a ready-made version of lambda s: s[1].

Python sorting is stable

Stable means that items with equal keys keep their original order. If Asha came before Meena in the list and both have 82 marks, Asha still comes first after sorting by marks. This lets you sort in steps: sort by the less important key first, then by the more important one.

max and min with key

python
students = [("Asha", 82), ("Ravi", 67), ("Meena", 91)]
print(max(students, key=lambda s: s[1]))
print(min(["kiwi", "banana", "fig"], key=len))
You do not need to sort the whole list just to find the top or bottom item.

Watch the lesson

Sorting with key · 1/6

Sorting with key

Sorting is everywhere: merit lists, cheapest products, top sellers. In this lesson you will sort by any rule you like.

Prefer a video by a teacher? Find free videos on “python sorted key lambda sorting tutorial” on YouTube ↗

In real life: Preparing a merit list

A school publishes a merit list: highest total first, and students with equal totals in alphabetical order. Principal Joseph also wants the topper and the student who needs the most help. One sorted call with a tuple key, plus max and min, does it all.

python
results = {"Ravi": 412, "Asha": 455, "Meena": 412, "Kabir": 389, "Zoya": 455}
merit = sorted(results, key=lambda name: (-results[name], name))
for rank, name in enumerate(merit, start=1):
    print(rank, name, results[name])
print("Topper:", max(results, key=results.get))
print("Needs help:", min(results, key=results.get))
Asha and Zoya tie at 455, so A comes before Z.

Practice (0/3 done)

Task 1 · Code · Python

Write by_length(words) that returns a new list of the words sorted from shortest to longest. Words of the same length keep their original order.

Task 2 · Code · Python

Write merit_list(marks) where marks is a dict of name to marks. Return a list of names, highest marks first. When two students have the same marks, put their names in A to Z order.

Task 3 · Code · Python

Write cheapest(products) where products is a list of dicts like {"name": "Soap", "price": 40}. Return the name of the product with the lowest price. Use min with a key.

Quick quiz

Question 1

1.What does nums.sort() return?

Question 2

2.What is sorted(["bb", "a", "ccc"], key=len)?

Question 3

3.Which key sorts (name, marks) pairs by marks high to low, then name A to Z?

Question 4

4.What does it mean that Python sorting is stable?

Question 5

5.What is max(["kiwi", "banana", "fig"], key=len)?

Read more (free)

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

← Previous: String processing