Sorting with sorted and key=
Overview
Python offers two ways to sort data: 1. **`list.sort()`**: Mutates the list in place. It returns `None`. 2. **`sorted(iterable)`**: Returns a *new* sorted list. The original iterable is unchanged. Both functions accept two optional keyword arguments: - `reverse=True`: Sorts descending instead of ascending. - `key=...`: A function (or lambda) that takes one element and returns a value to sort by. By default, sorting compares elements directly (numbers by value, strings alphabetically). But often you need to sort complex objects. By providing a `key` function, you tell Python exactly what aspect of the element to compare. For example, to sort a list of strings by their length: `sorted(words, key=len)`. To sort a list of intervals `[[1, 3], [2, 6], [8, 10]]` by their start time (the first element): `sorted(intervals, key=lambda x: x[0])`. To sort a dictionary's items by value instead of key: `sorted(d.items(), key=lambda item: item[1])`. Python's sort is **stable**. If two elements have the same key, they stay in the exact order they were originally in. This is extremely useful if you need to sort by multiple criteria (e.g. first sort by age, then sort by name).
Sorting is a fundamental building block. Many algorithms (like merging overlapping intervals or finding the k-th largest element) begin by sorting the input. Understanding `key=lambda...` means you can cleanly sort tuples, objects, or arrays by any arbitrary rule without writing complex comparator logic.
Where used: Sorting intervals by start time, Sorting pairs by the second element, Finding top-K elements
Why learn this
- You'll constantly need to sort lists of lists, tuples, or dicts in interviews.
- Using `.sort()` when you meant `sorted()` (or vice-versa) is a classic bug that deletes your data or mutates inputs you weren't supposed to touch.
Code walkthrough
intervals = [[8, 10], [1, 3], [2, 6]]
intervals.sort(key=lambda x: x[0])
print(intervals)
Focus: The lambda function `lambda x: x[0]` tells the sort algorithm: 'for each interval `x`, look at `x[0]` (the start time) to determine its order.' The list is mutated in place to `[[1, 3], [2, 6], [8, 10]]`.
Aha moment
words = ['banana', 'apple', 'cherry', 'kiwi']
by_len = sorted(words, key=len)
print(by_len)
Prediction: What is the order of the output?
Common guess: Alphabetical order
It prints `['kiwi', 'apple', 'banana', 'cherry']`. The `key` function is `len`, so Python calculates the length of each word and sorts by those numbers (4, 5, 6, 6). Notice 'banana' and 'cherry' both have length 6 — because the sort is stable, 'banana' stays before 'cherry' as it was in the original list.
Common mistakes
- Assigning the result of list.sort(): `result = arr.sort()` leaves `result` as `None`. `.sort()` mutates in place and doesn't return the list.
- Writing a custom comparator instead of a key: In older languages, you pass a function that compares two elements `f(a, b)`. In Python 3, you pass a `key` function that transforms one element into a sortable value `f(x)`.
- Mutating function arguments unnecessarily: If a function receives a list, calling `arr.sort()` modifies the caller's list. Unless instructed to modify in place, use `sorted(arr)` to return a new list.
Glossary
- stable sort
- A sorting algorithm that preserves the original relative order of elements that have equal sort keys. Python's `sort()` and `sorted()` are guaranteed to be stable.
Recall questions
- What is the difference between `a.sort()` and `sorted(a)`?
- How do you sort a list of strings in descending order?
- What does it mean that Python's sort is 'stable'?
Understanding checks
What is printed?
None
`items.sort()` mutates the list in place and returns `None`. To get the sorted list, you would just print `items`.
Is there a bug in this code?
No, this is perfectly valid.
This correctly sorts the list of tuples in place by the second element ('A', 'B'), modifying `records` to `[(2, 'A'), (1, 'B')]`.
What does this print?
9
The list is sorted in descending order (`reverse=True`), so the largest number (9) becomes the first element.
Practice tasks
Sort by the second value
You are given a list of `(name, age)` tuples. Modify the `sort_by_age` function to return a new list sorted by the person's age (the second element in each tuple), ascending.
Continue learning
Previous: Lists: indexing, slicing, methods
Previous: Lambda functions and when to use them