Sorting in Python: key, reverse, and Sorting by More Than One Field
sorted(items, key=...) is how you sort anything by something other than its default order: by length, by the second item of a pair, by a dictionary value. The key argument is a function that Python calls on each item to get the value to compare. Every example below was run in Python 3.13 and the output shown is what it printed.
1. The two ways to sort
The official sorting guide describes both. sorted() builds a new sorted list from any iterable and leaves the original alone. list.sort() changes the list in place and returns None, and it only exists for lists.
nums = [5, 2, 9, 1]
result = nums.sort()
print(result, nums)
None [1, 2, 5, 9]
result is None because sort() modifies the list and returns nothing. Writing nums = nums.sort() throws your list away.
2. Changing the comparison with key
The guide says key takes a function (or other callable) that receives one item and returns the value to sort by, and that Python calls it exactly once per item. A plain sort of mixed-case words puts capitalized words first:
words = "banana Cherry apple date Elderberry fig".split()
print(sorted(words))
print(sorted(words, key=str.casefold))
print(sorted(words, key=len))
['Cherry', 'Elderberry', 'apple', 'banana', 'date', 'fig']
['apple', 'banana', 'Cherry', 'date', 'Elderberry', 'fig']
['fig', 'date', 'apple', 'banana', 'Cherry', 'Elderberry']
The second line uses str.casefold, the same case-insensitive trick the guide demonstrates. The third sorts by length. Notice that you pass the function itself (len), not a call (len(...)). banana and Cherry both have 6 letters, and they stay in their original order, which is the next topic.
3. reverse=True and stability
Both sorted() and list.sort() accept reverse=True for a descending sort.
print(sorted(words, key=len, reverse=True))
print(words)
['Elderberry', 'banana', 'Cherry', 'apple', 'date', 'fig']
['banana', 'Cherry', 'apple', 'date', 'Elderberry', 'fig']
The original list is unchanged. Also, banana still comes before Cherry. The guide states that sorts are guaranteed to be stable: records with equal keys keep their original order, and reverse keeps that property too. So reverse=True does not simply flip the whole output.
4. Sorting records by a field
With tuples, use a small lambda to pick the field. Take four orders as (name, status, amount):
orders = [
("Ana", "pending", 30),
("Ben", "shipped", 12),
("Cy", "pending", 12),
("Dee", "shipped", 45),
]
print(sorted(orders, key=lambda o: o[2]))
[('Ben', 'shipped', 12), ('Cy', 'pending', 12), ('Ana', 'pending', 30), ('Dee', 'shipped', 45)]
Ben and Cy both have an amount of 12, and Ben stays first because he was first in the input. That is stability at work.
5. Sorting by two fields
To sort by status, then by amount inside each status, return a tuple from the key. Python compares tuples item by item.
print(sorted(orders, key=lambda o: (o[1], o[2])))
[('Cy', 'pending', 12), ('Ana', 'pending', 30), ('Ben', 'shipped', 12), ('Dee', 'shipped', 45)]
The guide also shows itemgetter from the operator module as a shorter, faster way to write the same thing:
from operator import itemgetter
print(sorted(orders, key=itemgetter(1, 2)))
[('Cy', 'pending', 12), ('Ana', 'pending', 30), ('Ben', 'shipped', 12), ('Dee', 'shipped', 45)]
The output matches the lambda version.
6. Mixed directions: sort twice
What if status should go A to Z but amount should go high to low? A tuple key cannot do that with plain numbers and text together, but stability can. The guide notes that stability lets you build complex sorts in steps. Sort by the least important field first, then by the most important:
step1 = sorted(orders, key=itemgetter(2), reverse=True)
step2 = sorted(step1, key=itemgetter(1))
print(step2)
[('Ana', 'pending', 30), ('Cy', 'pending', 12), ('Dee', 'shipped', 45), ('Ben', 'shipped', 12)]
The first pass orders by amount, high to low. The second pass groups by status, and because it is stable, each group keeps the amount order from the first pass.
7. Sorting a dictionary
Sorting a dictionary gives you its keys. To order by value, pass the lookup as the key:
scores = {"mia": 82, "leo": 91, "zed": 75}
print(sorted(scores))
print(sorted(scores, key=scores.get, reverse=True))
print(sorted(scores.items(), key=lambda kv: kv[1]))
['leo', 'mia', 'zed']
['leo', 'mia', 'zed']
[('zed', 75), ('mia', 82), ('leo', 91)]
The first two lines look identical here only because the names happen to be alphabetical in the same order as the scores, high to low. The third sorts the (name, score) pairs by score, lowest first.
8. Two common surprises
Text that looks like numbers sorts as text:
print(sorted(["10", "9", "2"]))
print(sorted(["10", "9", "2"], key=int))
['10', '2', '9']
['2', '9', '10']
Passing key=int converts each string to a number for the comparison only; the items stay strings. And mixing types that cannot be compared fails:
sorted([3, "a", 1])
TypeError: '<' not supported between instances of 'str' and 'int'
9. Key takeaways
sorted()returns a new list;list.sort()changes the list and returnsNone.keyis a function called once per item that returns the value to compare. Passlen, notlen(...).reverse=Truegives a descending sort and still keeps equal items in their original order.- Return a tuple from the key, or use
itemgetter, to sort by several fields. - Because Python sorts are stable, you can sort in passes, least important field first, to mix ascending and descending.
- Strings that look like numbers sort as text unless you use
key=int.
Sources
More on work & tech from other topics
- SUMIF vs SUMIFS, How to Sum With One or More Conditions · Spreadsheet Diary
- Fake Check and Reshipping Job Scams: How They Work · Remote Work Notes
- Can You Record a Zoom or Teams Meeting Without Telling People? Washington and Florida Law · AI at Work, Plainly