How to Implement Rich Comparison Ordering in Python Classes

This code demonstrates how to implement rich comparison operators (like <, <=, >, >=, ==, !=) in a Python class by defining __lt__ and __eq__, enabling sorting and ordering of custom objects.

Easy Python 3.9+ Aug 9, 2026 OOP & classes 12 views 0 copies

Python code

38 lines
Python 3.9+
class Task:
    def __init__(self, priority, name):
        self.priority = priority
        self.name = name

    def __lt__(self, other):
        if not isinstance(other, Task):
            return NotImplemented
        return self.priority < other.priority

    def __eq__(self, other):
        if not isinstance(other, Task):
            return NotImplemented
        return self.priority == other.priority

    def __repr__(self):
        return f"Task({self.priority}, '{self.name}')"


if __name__ == "__main__":
    tasks = [
        Task(5, "low"),
        Task(1, "critical"),
        Task(3, "medium"),
        Task(1, "urgent"),
    ]

    tasks.sort()
    print("Sorted:", tasks)

    a = Task(2, "a")
    b = Task(3, "b")
    print("a < b:", a < b)
    print("a <= b:", a <= b)
    print("a > b:", a > b)
    print("a >= b:", a >= b)
    print("a == b:", a == b)
    print("a != b:", a != b)

Output

stdout
Sorted: [Task(1, 'critical'), Task(1, 'urgent'), Task(3, 'medium'), Task(5, 'low')]
a < b: True
a <= b: True
a > b: False
a >= b: False
a == b: False
a != b: True

How it works

Python automatically derives the other comparison operators (<=, >, >=) from the __lt__ and __eq__ methods you provide, thanks to the default behavior of the standard library's functools.total_ordering decorator and the default ordering logic in Python 3. By defining __lt__ and __eq__, you give Python enough information to build a complete ordering. The __lt__ method returns NotImplemented when comparing with an incompatible type, which causes Python to fall back to comparing identity or raising a type error rather than guessing. This pattern ensures your custom objects can be sorted, compared, and used in any context that requires an ordered comparison.

Common mistakes

  • Only defining `__lt__` and `__eq__` while forgetting that `NotImplemented` should be returned (with capital N) for unsupported types
  • Overcomplicating by manually implementing all six comparison methods instead of relying on `__lt__` + `__eq__`
  • Defining comparison logic based on a field like `name` when you intend to sort by `priority`
  • Forgetting to handle `None` or other incompatible types in comparisons, leading to type errors

Variations

  1. Use `@functools.total_ordering` decorator explicitly when defining only `__eq__` and`__lt__`, which explicitly documents the decorator-based approach though Python 3 defaults already handle it
  2. Implement `__gt__` manually when you want different ascending/descending behavior beyond what the default derived comparison provides

Real-world use cases

  • Sorting a list of job objects by priority in a queue processing system
  • Comparing booking or reservation objects by timestamp to find the earliest available slot
  • Ordering database records by a human-readable field such as a product SKU within a reporting script

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from OOP & classes

Related tutorials and quizzes for this topic.