Use Python’s built-in sorting tools to organize data deterministically. The official Sorting Techniques guide covers the two core APIs—sorted()
and list.sort()
—including custom keys, descending order, and stability guarantees that preserve the order of equal items. See the documentation at docs.python.org. For the in-place method reference, see list.sort().
Method 1: Create a new sorted list with sorted()
Step 1: Call sorted(iterable)
to sort and return a new list.
nums = [5, 2, 9, 1]
sorted_nums = sorted(nums)
print(sorted_nums) # [1, 2, 5, 9]
Step 2: Verify the original sequence remains unchanged.
print(nums) # [5, 2, 9, 1]
Step 3: Add reverse=True
to sort in descending order.
sorted_desc = sorted(nums, reverse=True)
print(sorted_desc) # [9, 5, 2, 1]
Method 2: Sort a list in place with list.sort()
Step 1: Call your_list.sort()
to reorder the list in place.
a = [5, 2, 9, 1]
a.sort()
print(a) # [1, 2, 5, 9]
Step 2: Use reverse=True
to sort descending.
a.sort(reverse=True)
print(a) # [9, 5, 2, 1]
Step 3: Call sort()
without assigning its return value (it returns None
).
a = [3, 1, 2]
a.sort() # correct
# a = a.sort() # incorrect: a becomes None
Method 3: Apply custom criteria with the key=
parameter
Step 1: Sort strings case-insensitively by passing a normalization function as the key.
words = "This is a Test from Python".split()
ci = sorted(words, key=str.casefold)
print(ci) # ['a', 'from', 'is', 'Python', 'Test', 'This']
Step 2: Sort tuples by a specific field using operator.itemgetter
.
from operator import itemgetter
student_tuples = [
('john', 'A', 15),
('jane', 'B', 12),
('dave', 'B', 10),
]
by_age = sorted(student_tuples, key=itemgetter(2))
print(by_age) # [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
Step 3: Sort objects by attribute using operator.attrgetter
.
from operator import attrgetter
class Student:
def __init__(self, name, grade, age):
self.name, self.grade, self.age = name, grade, age
def __repr__(self):
return repr((self.name, self.grade, self.age))
students = [
Student('john', 'A', 15),
Student('jane', 'B', 12),
Student('dave', 'B', 10),
]
by_age = sorted(students, key=attrgetter('age'))
print(by_age) # [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
Step 4: Sort by absolute value using key=abs
(optionally descending with reverse=True
).
vals = [1, -5, 10, 6, 3, -4, -9]
by_abs_desc = sorted(vals, key=abs, reverse=True)
print(by_abs_desc) # [10, -9, 6, -5, -4, 3, 1]
Method 4: Multi-key and stable sorting
Step 1: Sort by multiple fields in one pass by passing multiple keys to itemgetter
or attrgetter
.
from operator import itemgetter
gradebook = [
('john', 'A', 15),
('dave', 'B', 10),
('jane', 'B', 12),
]
by_grade_then_age = sorted(gradebook, key=itemgetter(1, 2))
print(by_grade_then_age)
# [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
Step 2: Use two passes to mix ascending and descending orders; Python’s sort is stable, so the first order is preserved within equal keys.
from operator import attrgetter
class S:
def __init__(self, name, grade, age):
self.name, self.grade, self.age = name, grade, age
def __repr__(self): return repr((self.name, self.grade, self.age))
data = [S('john', 'A', 15), S('jane', 'B', 12), S('dave', 'B', 10)]
# First: secondary key (age ascending)
tmp = sorted(data, key=attrgetter('age'))
# Second: primary key (grade descending)
result = sorted(tmp, key=attrgetter('grade'), reverse=True)
print(result)
# [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
Tips, performance, and common pitfalls
Both sorted()
and list.sort()
use Timsort, which is stable and optimized for partially ordered data, and typically run in O(n log n) time. The key=
function is evaluated once per element, then comparisons use the computed keys. For deeper background on stability, multi-pass sorts, and comparison-function adapters, see the Python docs linked above.
- Need to keep the original data? Use
sorted()
, which returns a new list. - Want the fastest path for a list you plan to mutate? Use
list.sort()
to sort in place. - Don’t assign
a = a.sort()
; it returnsNone
. - For custom order, pass
key=
(e.g.,key=str.casefold
,key=itemgetter(...)
,key=attrgetter(...)
). - Use
reverse=True
for descending order; sort stability is preserved. - When memory is tight, prefer in-place sorting; when you need the original order elsewhere, prefer
sorted()
.
With these patterns, you can sort any iterable predictably—numbers, text, tuples, or objects—while controlling criteria and order with minimal code.
Member discussion