sorted() is the built-in for sorting any iterable. Unlike list.sort() (which sorts in place), sorted() returns a new list and works on anything iterable — including tuples, sets, generators, and strings.
The basics
nums: list[int] = [3, 1, 4, 1, 5, 9, 2, 6]
print(sorted(nums)) # [1, 1, 2, 3, 4, 5, 6, 9]
print(nums) # unchanged
# descending
print(sorted(nums, reverse=True)) # [9, 6, 5, 4, 3, 2, 1, 1]
You can sort strings (alphabetically by character code):
print(sorted("python")) # ['h', 'n', 'o', 'p', 't', 'y']
Sorting by a custom key
The most powerful feature of sorted() is the key argument — a function that returns the value to sort by.
words: list[str] = ["banana", "fig", "apple", "kiwi"]
# sort by length
by_length: list[str] = sorted(words, key=len)
print(by_length) # ['fig', 'kiwi', 'apple', 'banana']
# sort by last letter
by_last: list[str] = sorted(words, key=lambda w: w[-1])
print(by_last) # ['banana', 'apple', 'fig', 'kiwi']
The key function is called once per item; the returned value decides the order. The items themselves still appear in the output — only the order changes.
Sorting dictionaries (and lists of dictionaries)
A common task: sort a list of records by one of their fields.
people: list[dict[str, str | int]] = [
{"name": "alice", "age": 30},
{"name": "bob", "age": 25},
{"name": "carol", "age": 35},
]
by_age: list[dict[str, str | int]] = sorted(people, key=lambda p: p["age"])
for p in by_age:
print(p)
{'name': 'bob', 'age': 25}
{'name': 'alice', 'age': 30}
{'name': 'carol', 'age': 35}
Sorting tuples — natural ordering
A tuple sorts by its first item, then second, then third. Useful when you want to break ties:
people: list[tuple[str, int]] = [
("alice", 30),
("bob", 25),
("alice", 28),
]
# sort by name, then by age within the same name
ordered = sorted(people)
print(ordered)
# [('alice', 28), ('alice', 30), ('bob', 25)]
Sorting with multiple keys
To sort by multiple criteria, return a tuple from the key function:
people: list[dict[str, str | int]] = [
{"name": "alice", "age": 30},
{"name": "bob", "age": 25},
{"name": "alice", "age": 28},
]
# sort by name (ascending) then by age (ascending)
ordered = sorted(people, key=lambda p: (p["name"], p["age"]))
To mix ascending and descending, negate the numeric field:
# name ascending, age descending
ordered = sorted(people, key=lambda p: (p["name"], -p["age"]))
Reversing
reverse=True reverses the whole sort:
print(sorted([3, 1, 4, 1, 5], reverse=True)) # [5, 4, 3, 1, 1]
It’s not the same as sorting normally then reversing — reverse=True is the cleaner way and keeps stable ordering intact (see below).
Stable sort
Python’s sort is stable — items with equal keys keep their original order. This matters when you sort by multiple criteria in stages:
people = [
{"name": "alice", "age": 30},
{"name": "bob", "age": 25},
{"name": "alice", "age": 28},
]
# sort by age, then sort by name
step1 = sorted(people, key=lambda p: p["age"])
step2 = sorted(step1, key=lambda p: p["name"])
Because the sort is stable, the age order is preserved within each name group. Same result as the tuple-key approach, just split into stages.
list.sort() vs sorted()
nums: list[int] = [3, 1, 4]
nums.sort() # in place — nums is now [1, 3, 4], returns None
result = sorted(nums) # returns a new sorted list — nums unchanged
Use sorted() when:
- You don’t want to modify the original
- You’re sorting something that isn’t a list (a tuple, set, dict view, generator)
Use list.sort() when:
- You have a list and don’t need to keep the original order
A real-world example — top N
Sort and slice to get the top N:
products = [
{"name": "a", "price": 9.99},
{"name": "b", "price": 4.50},
{"name": "c", "price": 14.00},
{"name": "d", "price": 2.00},
]
top_3_cheapest = sorted(products, key=lambda p: p["price"])[:3]
for p in top_3_cheapest:
print(p)
For very large data, the standard library has heapq.nsmallest and heapq.nlargest, which are faster when N is small relative to the total. Most of the time, sorted()[:n] is plenty.
What’s next
Last lesson of this section — any and all, two tiny built-ins that read like English.