Python Sorted List of Tuples: Sorting by Key and Order
python sorted list of tuples: Learn how to sort a list of tuples in Python by any element using sorted() with key functions, itemgetter, reverse order, and in-place so...
The default behavior of sorted() on a list of tuples compares tuples element by element. When you pass a list of tuples to sorted(), Python compares the first elements, and if they are equal, compares the second elements, and so on. This lexicographic ordering is often exactly what you need, but it is not always the intended order. Understanding how to control the sort key is the core skill behind working with a python sorted list of tuples.
The Default Sort Order for a List of Tuples
records = [(3, "alice"), (1, "bob"), (2, "carol")] sorted_records = sorted(records) print(sorted_records) # [(1, "bob"), (2, "carol"), (3, "alice")]
The tuples are compared position by position. The first element is the primary sort key, and the second element breaks ties. This works well when the first element is the field you want to order by, but it becomes a problem when you need to sort by the second element, or when the first elements are not comparable.
Sorting by a Specific Tuple Index with key
To sort by a different element, pass a key function that returns the value to compare:
records = [(3, "alice"), (1, "bob"), (2, "carol")] sorted_by_name = sorted(records, key=lambda t: t[1]) print(sorted_by_name) # [(3, "alice"), (1, "bob"), (2, "carol")]
The key function is called once per element, and the returned value is used as the comparison key. The original tuples are never modified. This is the standard way to sort a list of tuples by any single field.
Using operator.itemgetter for Cleaner Key Functions
For tuple indexing, operator.itemgetter is more readable and slightly faster than a lambda:
from operator import itemgetter records = [(3, "alice"), (1, "bob"), (2, "carol")] sorted_by_name = sorted(records, key=itemgetter(1))
itemgetter(1) returns a callable that fetches index 1 from each tuple. When you need to sort by multiple fields, itemgetter also accepts multiple indices: itemgetter(0, 1) sorts by the first element and then by the second.
Reversing the Sort Order
Pass reverse=True to sort in descending order:
sorted_desc = sorted(records, key=itemgetter(1), reverse=True)
Note that reverse applies after the key function is evaluated. If you need descending order on one field and ascending on another, you cannot express that with a single reverse flag. You would need to negate a numeric key, or sort twice with stable sorting.
Sorting In Place with list.sort()
The sorted() function returns a new list and leaves the original untouched. If you do not need the original order, use list.sort() to sort in place:
records.sort(key=itemgetter(1))
This avoids allocating a second list, which matters when the list is large. The same key and reverse arguments are available.
| Aspect | sorted() | list.sort() |
|---|---|---|
| Returns | New list | None |
| Original list | Unchanged | Modified in place |
| Memory | Extra list allocation | No extra list |
| Use case | Keep original order | No need for original |
Performance: How the Key Function Affects Sorting Cost
The key function is called exactly once per element, and the results are cached internally by the sorting algorithm. This is why key=itemgetter(1) is much faster than a comparison function that recomputes values during each comparison. The Timsort algorithm used by Python is stable, so elements with equal keys retain their original relative order. That stability matters when you sort by multiple criteria in separate passes: sorting by the secondary key first, then by the primary key, produces a correctly ordered result.
Edge Cases and Common Mistakes
A common mistake is sorting a list of tuples where the first elements are of different types. Python cannot compare an int with a str, and the sort raises a TypeError. If your data may contain mixed types, normalize the key values before sorting.
Another mistake is assuming that sorted() modifies the original list. It does not. If you forget to assign the result, the original order remains unchanged.
Tuples of different lengths also compare fine lexicographically as long as the common prefix is equal; the shorter tuple is considered smaller. This is rarely what you want in real data, so be explicit about the key when tuple lengths vary.