W3docs

Sort Lists

Learn how to sort Python lists with sorted() and sort(), use the key parameter, sort in reverse, and handle custom objects with clear examples.

Sorting a list is one of the most common operations in Python. Python gives you two built-in tools for this: the sorted() function, which returns a new sorted list without changing the original, and the list.sort() method, which reorders the list in place. Both accept a reverse flag for descending order and a key parameter for custom sort logic.

This chapter covers:

  • sorted() — sort any iterable into a new list
  • list.sort() — sort a list in place
  • Sorting in ascending and descending order
  • The key parameter — sort by length, field, or any custom criterion
  • Case-insensitive sorting
  • Sorting lists of dictionaries and custom objects
  • Multi-key sorting
  • operator.itemgetter as an efficient alternative to lambda

For a refresher on list fundamentals, see the Python Lists and List Methods chapters.

The sorted() Function

sorted() takes any iterable (list, tuple, string, …) and returns a new sorted list. The original iterable is left unchanged.

Syntax:

sorted(iterable, *, key=None, reverse=False)
  • iterable — the sequence to sort
  • key — an optional one-argument function applied to each element before comparing (default: compare elements directly)
  • reverse — set to True to sort in descending order (default: False)

Sort a list of strings

python— editable, runs on the server

Sort a list of numbers

Numeric lists sort by magnitude, not by string representation (so 10 does not sort before 9).

nums = [3, 1, 4, 1, 5, 9, 2, 6]
print(sorted(nums))
# [1, 1, 2, 3, 4, 5, 6, 9]

Sort in descending order with reverse=True

Pass reverse=True to get the largest values first.

nums = [3, 1, 4, 1, 5, 9, 2, 6]
print(sorted(nums, reverse=True))
# [9, 6, 5, 4, 3, 2, 1, 1]

The list.sort() Method

list.sort() reorders the list in place and always returns None. Use it when you no longer need the original order and want to avoid the memory overhead of a second list.

Syntax:

list.sort(*, key=None, reverse=False)

The parameters are identical to sorted().

Sort a list in place

python— editable, runs on the server

Sort in descending order

python— editable, runs on the server

sort() returns None — a common pitfall

A frequent mistake is assigning the result of sort() to a variable:

fruits = ['banana', 'apple', 'cherry']
result = fruits.sort()   # sort() modifies fruits, returns None
print(result)            # None  ← not the sorted list!
print(fruits)            # ['apple', 'banana', 'cherry']  ← fruits was modified

If you need both the sorted result and the original order, use sorted() instead.

sorted() vs list.sort() — When to Use Which

sorted()list.sort()
ReturnsA new sorted listNone
Original listUnchangedModified in place
Works onAny iterableLists only
MemoryUses extra memoryNo extra list

Use sorted() when you need the original unchanged, or when sorting a tuple or other iterable.

Use list.sort() when you have a list, you want to sort it in place, and memory efficiency matters.

Sorting with the key Parameter

The key parameter accepts a one-argument callable. Python calls it once on each element and uses the returned value for comparisons. This avoids duplicating data and makes sorting flexible.

Sort by string length

words = ['banana', 'apple', 'cherry', 'kiwi']
print(sorted(words, key=len))
# ['kiwi', 'apple', 'banana', 'cherry']

len is passed directly — no lambda needed when using a built-in function that takes one argument.

Sort a list of tuples by a specific field

python— editable, runs on the server

The lambda lambda x: x[1] extracts the second element (the number) from each tuple so Python compares numbers instead of whole tuples.

Sort a list of dictionaries

students = [
    {'name': 'Charlie', 'grade': 85},
    {'name': 'Alice',   'grade': 92},
    {'name': 'Bob',     'grade': 78},
]

by_grade = sorted(students, key=lambda s: s['grade'])
for s in by_grade:
    print(s['name'], s['grade'])
# Bob 78
# Charlie 85
# Alice 92

To sort in descending order (highest grade first), add reverse=True:

by_grade_desc = sorted(students, key=lambda s: s['grade'], reverse=True)
for s in by_grade_desc:
    print(s['name'], s['grade'])
# Alice 92
# Charlie 85
# Bob 78

Case-insensitive sorting

By default, Python's sort is case-sensitive: all uppercase letters come before lowercase letters because they have lower Unicode code points. Use key=str.lower to sort without regard to case.

words = ['Banana', 'apple', 'Cherry', 'date']
print(sorted(words))             # case-sensitive (uppercase first)
# ['Banana', 'Cherry', 'apple', 'date']

print(sorted(words, key=str.lower))  # case-insensitive
# ['apple', 'Banana', 'Cherry', 'date']

Using operator.itemgetter and operator.attrgetter

The operator module provides faster alternatives to lambda for common key patterns.

operator.itemgetter — for sequences and dicts

import operator

fruits = [('apple', 10), ('banana', 5), ('cherry', 20)]
print(sorted(fruits, key=operator.itemgetter(1)))
# [('banana', 5), ('apple', 10), ('cherry', 20)]

operator.itemgetter(1) is equivalent to lambda x: x[1] but is implemented in C and runs faster on large lists.

operator.attrgetter — for objects

import operator

class Student:
    def __init__(self, name, grade):
        self.name = name
        self.grade = grade
    def __repr__(self):
        return f'Student({self.name!r}, {self.grade})'

students = [Student('Charlie', 85), Student('Alice', 92), Student('Bob', 78)]
print(sorted(students, key=operator.attrgetter('grade')))
# [Student('Bob', 78), Student('Charlie', 85), Student('Alice', 92)]

Multi-Key Sorting

Return a tuple from the key function to sort by multiple criteria. Python compares tuples element-by-element, so ties on the first key fall through to the second.

# Sort by grade ascending, then by name alphabetically when grades tie
data = [('Alice', 85), ('Bob', 92), ('Charlie', 85), ('Dave', 78)]
result = sorted(data, key=lambda x: (x[1], x[0]))
print(result)
# [('Dave', 78), ('Alice', 85), ('Charlie', 85), ('Bob', 92)]

Alice and Charlie both have grade 85, so they are sorted alphabetically — Alice before Charlie.

Sort Stability

Python's sort is stable: elements that compare equal keep their original relative order. This means you can sort a list by one key, then sort the result by another key, and the first sort's order is preserved within ties of the second key.

# Sort by grade, then (stably) by name — same result as the tuple key above
data = [('Alice', 85), ('Bob', 92), ('Charlie', 85), ('Dave', 78)]
step1 = sorted(data, key=lambda x: x[0])   # sort by name first
step2 = sorted(step1, key=lambda x: x[1])  # then sort by grade
print(step2)
# [('Dave', 78), ('Alice', 85), ('Charlie', 85), ('Bob', 92)]

This technique — called a Schwartzian transform — is sometimes more readable than a composite key.

Conclusion

Python's sorted() and list.sort() give you fast, flexible list sorting with minimal code. Use sorted() when you need a new list or are sorting a non-list iterable; use list.sort() when you want to modify a list in place. The key parameter handles almost any sorting criterion — from sorting by length or a dict field to case-insensitive comparisons. For large datasets, prefer operator.itemgetter or operator.attrgetter over lambda for better performance.

Related reading:

Practice

Practice
Which of the following statements about sorted() and list.sort() are true?
Which of the following statements about sorted() and list.sort() are true?
Was this page helpful?