pythonoopquicksortcomparablekeyvaluepair

How do I make my class comparable in Python?


I have a Pair class (it has a key and a value) and I'm trying to make a program which creates a bunch of Pair objects, adds them to a list, and performs stable quicksort on them. However, I can't seem to figure how to make the objects comparable so that the program automatically compares the keys of two objects when they have the same value. It's so easy to do this in Java but I just don't get how I'm supposed to do the equivalent in Python.

Thank you in advance!

class Pair(Generic[K,V]):
    def __init__(self, key: K, val: V):
        self.key = key
        self.value = val

Solution

  • How about the following (Pair sortable by key but you can easily define any other way to sort them):

    class Pair:
        def __init__(self, key, val):
            self.key = key
            self.value = val
    
        def __eq__(self, other: "Pair"):
            return self.key == other.key
    
        def __lt__(self, other: "Pair"):
            return self.key < other.key
    
        def __le__(self, other: "Pair"):
            return self.key <= other.key
    
        def __gt__(self, other: "Pair"):
            return self.key > other.key
    
        def __ge__(self, other: "Pair"):
            return self.key >= other.key
    
        def __str__(self):
            return f"{self.key}={self.value}"
    
        def __repr__(self):
            return f"{self.key}={self.value} ({id(self)})"
    
    
    test = [
        Pair("a2", "1"), Pair("a1", "2"), Pair("b1", "3"),Pair("br", "4")
    ]
    
    print(sorted(test))
    

    Output:

    $ python3 ~/tmp/test.py
    [a1=2 (4352627216), a2=1 (4352622288), b1=3 (4352627344), br=4 (4352627408)]
    

    To sort by value and then by key if the values are equal you would dp something like:

        def __lt__(self, other: "Pair"):
            if self.value != other.value:
                return self.value < other.value
    
            return self.key < other.key
    

    example input/output with the above lt:

    # Input
    test = [
        Pair("a2", "1"), Pair("a1", "2"), Pair("b1", "1"),Pair("br", "4")
    ]
    
    # Output
    [a2=1 (4466773648), b1=1 (4466778768), a1=2 (4466778640), br=4 (4466778832)]
    

    Additionally, if you plan to use the pairs as dictionary keys or in sets you can implement __hash__. For more operators see here