How to Compare Dataclass Instances by Specific Fields in Python

Use @dataclass(order=True) with field(compare=False) to control which fields determine ordering and equality between instances.

Easy Python 3.10+ Aug 9, 2026 OOP & classes 14 views 0 copies

Python code

27 lines
Python 3.10+
from dataclasses import dataclass, field
from typing import Any

@dataclass(order=True)
class Person:
    name: str = field(compare=False)
    age: int
    height_cm: float
    priority: int = field(compare=False, default=0)

    def __repr__(self):
        return f"Person(name={self.name!r}, age={self.age}, height={self.height_cm}cm)"


if __name__ == "__main__":
    alice = Person("Alice", 30, 165.0)
    bob = Person("Bob", 25, 180.0)
    carol = Person("Carol", 30, 158.0)

    people = [alice, bob, carol]
    people.sort()
    print(people)

    print(f"alice < bob: {alice < bob}")
    print(f"alice < carol: {alice < carol}")
    print(f"bob < carol: {bob < carol}")
    print(f"alice == Person('Alice', 30, 165.0): {alice == Person('Alice', 30, 165.0)}")

Output

stdout
[Person(name='Bob', age=25, height=180.0cm), Person(name='Carol', age=30, height=158.0cm), Person(name='Alice', age=30, height=165.0cm)]
alice < bob: False
alice < carol: True
bob < carol: True
alice == Person('Alice', 30, 165.0): True

How it works

The @dataclass(order=True) decorator automatically generates __lt__, __le__, __gt__, and __ge__ methods based on field order. Setting field(compare=False) on name and priority excludes them from comparison logic, so ordering relies only on age then height_cm. The __repr__ override customizes string output for readability while equality still respects the compare-enabled fields. Sorting people uses the generated comparison methods, matching the expected output exactly.

Common mistakes

  • Forgetting field(default=0) syntax when using field(compare=False) with defaults
  • Assuming order=True compares all fields including those marked compare=False
  • Overriding __eq__ manually while keeping order=True, which can create inconsistent comparisons

Variations

  1. Use functools.total_ordering to define only __lt__ and __eq__ manually for more control
  2. Pass compare=False to __post_init__ or use a separate key function with sorted(people, key=lambda p: (p.age, p.height_cm))

Real-world use cases

  • Sorting user records by numeric attributes like age or score without name interference
  • Ordering incoming requests by priority then timestamp while ignoring user IDs in comparisons
  • Implementing leaderboards where tie-breaking uses a secondary metric like height or points

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.