tags:

views:

138

answers:

3

Hi,

I'm trying to sort a list of objects according to my criteria.

Here is my sorting function:

def sort_pots(self, pot1, pot2):
    coeff1 = ((pot1.movable + pot1.convertible) / pot1.total)
    coeff2 = ((pot2.movable + pot2.convertible) / pot2.total)

    if coeff1 > coeff2:
        return 1
    elif coeff1 == coeff2:
        return pot1.total - pot2.total
    else:
        return -1

What i would like to achieve is: if coeff1 > coeff2, pot1 is before pot2 if coeff1 == coeff2, the one with the highest total is before else (coeff2 > coeff1), pot2 is before pot2

and the function doesn't seem to work accordingly. I've got a bunch ordered according to total but not with same coeff. I've (convertible, movable, total): 0, 0, 1 and later 0, 3, 4 and then 31, 228, 1584 and then 1, 0, 1

Here is the beginning of the definition of the class of pot1 and pot2:

class Potential:
    def __init__(self,conf_opt):
        self.conf_opt = conf_opt
        self.total = 0
        self.movable = 0
        self.convertible = 0

thanks.

+9  A: 

Does the following work?

def coef(pot):
    return (pot.movable + pot.convertible) / float(pot.total)

l.sort(key=lambda x: (coef(x), x.total), reverse=True)

It should even be faster (key is better than cmp).

tonfa
He wants to sort descending, so `reverse=True`.
Stephan202
Right, thank you.
tonfa
+1  A: 

I think tonfa's answer is the most readable but if you want to do it with the code you have you should try:

def sort_pots(self, pot1, pot2):
    coeff1 = ((pot1.movable + pot1.convertible) / pot1.total)
    coeff2 = ((pot2.movable + pot2.convertible) / pot2.total)

    if coeff1 > coeff2:
        return 1
    elif coeff1 == coeff2:
        return cmp(pot1.total,pot2.total)
    else:
        return -1

Edit: Used cmp method rather than long form if/else

Jesse
if you want to do that, just call `-cmp(pot1.total, pot2.total)`.
tonfa
just returning 1 or -1 makes the difference ?
LB
+2  A: 

Just as a final note, you could override the __cmp__ method as follows:

class Potential(object): # new style classes FTW!
    ...
    def __cmp__(self, other):
        coeff1 = (self.movable + self.convertible) / self.total
        coeff2 = (other.movable + other.convertible) / other.total
        return cmp((coeff1, self.total), (coeff2, other.total))

That way, the normal sorting order is achieved just by calling sort() with no arguments. You might even make the suggested coeff function a part of your class:

class Potential(object):
    ...
    def coeff(self):
        return (self.movable + self.convertible) / self.total

    def __cmp__(self, other):
        return cmp((self.coeff(), self.total), (other.coeff(), other.total))
Chris Lutz