How to Sort Data in Python
Sort sequences with type-safe helpers that handle mixed data with a string fallback.
Python code
34 linesfrom typing import Any, TypeVar, Protocol, Sequence, Iterable
T = TypeVar("T")
Comparable = TypeVar("Comparable", bound="Comparable")
class Sortable(Protocol):
def __lt__(self, other: Any) -> bool: ...
S = TypeVar("S", bound=Sortable)
def sort_data(data: Sequence[S], *, reverse: bool = False) -> list[S]:
"""Return a new sorted list (does not modify the input)."""
return sorted(data, reverse=reverse)
def sort_any(data: Iterable[Any], *, reverse: bool = False) -> list[Any]:
"""Fallback for mixed types; coerce failures to str for display."""
items = list(data)
try:
return sorted(items, reverse=reverse)
except TypeError:
return sorted(items, key=str, reverse=reverse)
if __name__ == "__main__":
numbers = [3, 1, 2]
words = ["banana", "apple", "cherry"]
print("Numbers ascending:", sort_data(numbers))
print("Numbers descending:", sort_data(numbers, reverse=True))
print("Words alphabetical:", sort_data(words))
mixed: list[Any] = [5, "x", 2, "a"]
print("Mixed (string fallback):", sort_any(mixed))
Output
Numbers ascending: [1, 2, 3]
Numbers descending: [3, 2, 1]
Words alphabetical: ['apple', 'banana', 'cherry']
Mixed (string fallback): ['x', '5', '2', 'a']
How it works
The sort_data function uses a Sortable Protocol to accept any type with a __lt__ method, ensuring runtime safety through static type checking. TypeVar with a bound preserves the element type in the returned list. The sort_any fallback catches TypeError when mixing incompatible types (e.g., int and str) and sorts by string representation, which is useful for display. Both functions are generic to work with any iterable or sequence without modifying the original input.
Common mistakes
- Forgetting that `sorted()` returns a new list, while `.sort()` mutates in place.
- Expecting mixed types to sort without a key; Python raises TypeError for int/str comparisons.
- Using `Sequence` when you only need to iterate, which rejects generators.
- Overlooking reverse parameter to sort descending.
Variations
- Use `data.sort()` when you want to mutate the original list and save memory.
- Use `sorted(data, key=str.lower)` for case-insensitive string sorting.
Real-world use cases
- Sorting API response data by a field before presenting it in a dashboard.
- Ordering user-generated content like comments by timestamp or votes.
- Normalizing mixed-type log entries for consistent display in debugging tools.
Sponsored
More from Testing & modern typing
- Capture stdout and stderr with pytest capsys easy
- Characterization Test for Legacy Python Code medium
- Dataclass with Type Hints Fields in Python easy
- Dependency Injection in Python for Testability easy
- Design Data Helpers with Python TypedDict and Literal easy
- Fix and Test a Regression Bug in Python with Unit Tests easy
Keep learning
Related tutorials and quizzes for this topic.