Python Equivalent of Java's compareTo()

Python Equivalent of Java's compareTo()

I'm doing a project in Python (3.2) for which I need to compare user defined objects. I'm used to OOP in Java, where one would define a compareTo() method in the class that specifies the natural ordering of that class, as in the example below:

public class Foo {
    int a, b;

    public Foo(int aa, int bb) {
        a = aa;
        b = bb;
    }

    public int compareTo(Foo that) {
        // return a negative number if this < that
        // return 0 if this == that
        // return a positive number if this > that

        if (this.a == that.a) return this.b - that.b;
        else return this.a - that.a;
    }
}

I'm fairly new to classes/objects in Python, so I'd like to know what is the "pythonic" way to define the natural ordering of a class?

1

2 Answers

You can implement the special methods __lt__, __gt__ etc. to implement the default operators for custom types. See more about them in the language reference.

For example:

class Foo:
    def __init__ (self, a, b):
        self.a = a
        self.b = b

    def __lt__ (self, other):
        if self.a == other.a:
            return self.b < other.b
        return self.a < other.b

    def __gt__ (self, other):
        return other.__lt__(self)

    def __eq__ (self, other):
        return self.a == other.b and self.b == other.b

    def __ne__ (self, other):
        return not self.__eq__(other)

Or as said by stranac in the comments, you can use the total_ordering decorator to save some typing:

@functools.total_ordering
class Foo:
    def __init__ (self, a, b):
        self.a = a
        self.b = b

    def __lt__ (self, other):
        if self.a == other.a:
            return self.b < other.b
        return self.a < other.b

    def __eq__ (self, other):
        return self.a == other.b and self.b == other.b
4

Python has a similar function: __cmp__().

I now see you're asking about Python 3. Their "whats new" suggests:

The cmp() function should be treated as gone, and the __cmp__() special method 
is no longer supported. Use __lt__() for sorting, __eq__() with __hash__(), and 
other rich comparisons as needed. (If you really need the cmp() functionality, 
you could use the expression (a > b) - (a < b) as the equivalent for cmp(a, b).)

So it seems you could always do something like

def compareTo(self, that):
    return ((self > that) - (self < that))

or

@classmethod
def compare(cls, a, b):
    return ((a > b) - (a < b))

after implementing __gt__() and __lt__().

Which you would then use like:

f1 = Foo(1,1)
f2 = Foo(2,2)

f1.compareTo(f2)
Foo.compare(f1,f2)

This would give you equivalent functionality.

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Robert Thorne
Author

Robert Thorne

Robert Thorne covers electric vehicle innovations, autonomous driving systems, global mobility trends, and automotive engineering developments.