Trouble with max() and __cmp__()

Jean-Paul Calderone exarkun at divmod.com
Sun Jan 28 16:08:13 EST 2007


On 28 Jan 2007 12:46:07 -0800, Thomas Nelson <thn at mail.utexas.edu> wrote:
>My code:
>
>class Policy(list):
>    def __cmp__(self,other):
>        return cmp(self.fitness,other.fitness)
>
>j = Policy()
>j.fitness = 3
>k = Policy()
>k.fitness = 1
>l = Policy()
>l.fitness = 5
>print max([j,k,l]).fitness
>
>prints 3, when I was expecting it to print 5.  What have I done wrong?
>

max() uses >, apparently.  Which means the builtin list.__gt__ is consulted,
not your __cmp__ implementation:

    >>> class x(list):
    ...     def __cmp__(self, other):
    ...             print 'yes'
    ...             return 1
    ...
    >>> max([x(), x(), x()])
    []
    >>> class y(list):
    ...     def __lt__(self, other):
    ...             print 'yes'
    ...             return cmp(id(self), id(other))
    ...
    >>> max([y(), y(), y()])
    []
    >>> class z(list):
    ...     def __le__(self, other):
    ...             print 'yes'
    ...             return cmp(id(self), id(other))
    ...
    >>> max([z(), z(), z()])
    []
    >>> class w(list):
    ...     def __ge__(self, other):
    ...             print 'yes'
    ...             return cmp(id(self), id(other))
    ...
    >>> max([w(), w(), w()])
    []
    >>> class v(list):
    ...     def __gt__(self, other):
    ...             print 'yes'
    ...             return cmp(id(self), id(other))
    ...
    >>> max([v(), v(), v()])
    yes
    yes
    []

Note that this is different from the operation used by list.sort():

    >>> [v(), v(), v()].sort()
    >>> [w(), w(), w()].sort()
    >>> [x(), x(), x()].sort()
    >>> [z(), z(), z()].sort()
    >>> [y(), y(), y()].sort()
    yes
    yes
    >>>

So, if you implement __gt__, max will work right.  If you also implement
__le__, sorting will work right.  Your best bet is probably to implement
all of the rich comparison methods.

Jean-Paul



More information about the Python-list mailing list