Python Sorted Reverse: Descending Order Sorting
python sorted reverse: Learn how sorted(reverse=True) orders Python iterables in descending order, how it interacts with key functions, and when to prefer list.sort().
Python's sorted(reverse=True) sorts any iterable in descending order and returns a new list. This python sorted reverse combination is the standard approach for descending-order sorting in Python. The reverse keyword argument controls the direction of the sort:
scores = [88, 92, 79, 95, 84] ranked = sorted(scores, reverse=True) print(ranked) # [95, 92, 88, 84, 79]
The function returns a new list and leaves the original iterable untouched. This is the key difference from list.sort(), which mutates the list in place and returns None.
The reverse parameter defaults to False, so sorted(data) and sorted(data, reverse=False) produce identical results. Passing reverse=True is the only way to request descending order through the sorted() API.
How reverse Interacts with the key Parameter
The key parameter transforms each element before comparison. The reverse flag applies to the final ordering, not to the key transformation itself.
words = ["kiwi", "apple", "banana", "cherry", "date"] by_length = sorted(words, key=len, reverse=True) print(by_length) # ['banana', 'cherry', 'apple', 'kiwi', 'date']
Here len determines the sort key for each word, and reverse=True orders the words from longest to shortest. Words of equal length retain their original relative order because Python's sort is stable.
The same principle applies when the key is a lambda or a callable from the operator module:
from operator import itemgetter records = [ {"name": "alpha", "score": 42}, {"name": "beta", "score": 87}, {"name": "gamma", "score": 55}, ] top_first = sorted(records, key=itemgetter("score"), reverse=True)
The itemgetter("score") callable extracts the score field from each dictionary, and reverse=True places the highest score first.
sorted() vs list.sort() for Descending Order
Both sorted() and list.sort() accept reverse=True, but they serve different purposes.
data = [5, 2, 8, 1, 9] # Returns a new list new_list = sorted(data, reverse=True) # Mutates the existing list data.sort(reverse=True)
Use sorted() when you need to keep the original data intact, such as when the list is shared with other parts of the program or when you need both the original and sorted versions. Use list.sort() when the original order is no longer needed and you want to avoid the memory cost of a second list.
For large datasets, list.sort() avoids allocating a new list, which matters when memory is constrained. sorted() is the only option for iterables that are not lists, such as tuples, sets, generators, or dictionary views.
Sorting Objects by an Attribute in Reverse
When sorting a collection of objects, the key parameter extracts the attribute used for comparison. The attrgetter helper from the operator module keeps the code readable:
from operator import attrgetter class Task: def __init__(self, name, priority, due): self.name = name self.priority = priority self.due = due tasks = [ Task("write docs", 2, 3), Task("fix bug", 5, 1), Task("deploy", 4, 2), ] by_priority = sorted(tasks, key=attrgetter("priority"), reverse=True)
The result orders tasks by priority from highest to lowest. If two tasks share the same priority, their original relative order is preserved because the sort is stable.
For a secondary sort, sort by the secondary key first, then by the primary key with reverse=True. Stability ensures the secondary ordering survives the second pass:
by_due_then_priority = sorted( sorted(tasks, key=attrgetter("due")), key=attrgetter("priority"), reverse=True, )
This produces tasks ordered by priority descending, with ties broken by due date ascending.
Stability and Multi-Pass Reverse Sorting
Python's sorted() is guaranteed to be stable. Equal elements keep their original relative order, even when reverse=True is set. This guarantee is what makes the multi-pass pattern above reliable.
The stability guarantee has a practical consequence: if you reverse the list after sorting instead of using reverse=True, the relative order of equal elements also reverses. These two approaches are not equivalent:
data = [("a", 1), ("b", 1), ("c", 2)] # reverse=True preserves original order of equal keys result_a = sorted(data, key=lambda x: x[1], reverse=True) # [('c', 2), ('a', 1), ('b', 1)] # reversing after sorting flips equal-key order result_b = sorted(data, key=lambda x: x[1])[::-1] # [('c', 2), ('b', 1), ('a', 1)]
When the relative order of equal elements matters, use reverse=True rather than reversing the sorted list.
Performance and Memory Behavior
sorted() always creates a new list, so it requires O(n) additional memory for the result. list.sort() sorts in place and avoids that allocation, which can be significant for large lists.
The underlying Timsort algorithm is O(n log n) in the worst case and O(n) for already-sorted or nearly-sorted input. Setting reverse=True does not change the algorithmic complexity; it only reverses the comparison direction.
For a generator or other non-sequence iterable, sorted() must materialize the elements into a list before sorting, so memory usage is O(n) regardless. If the input is already a list and the original order is expendable, list.sort(reverse=True) is the more memory-efficient choice.
Handling None Values and Mixed Types
Sorting fails with a TypeError when elements cannot be compared. This commonly happens with None values mixed into a list of numbers or strings:
values = [10, None, 5, None, 8] # sorted(values, reverse=True) # TypeError
To handle None values explicitly, provide a key that maps them to a comparable sentinel:
values = [10, None, 5, None, 8] sorted_values = sorted(values, key=lambda x: (x is not None, x), reverse=True) # Result: [10, 8, 5, None, None]
The key produces a tuple for each element. The first tuple element separates None from real values: None maps to False, and every other value maps to True. With reverse=True, True sorts before False, so numeric values come first and None values come last. Within each group, the second tuple element determines the order.
Mixed numeric and string types also raise TypeError. There is no implicit conversion in Python's sort, so the data must be normalized before sorting.