1

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.

1
  • I guess <code>return pot1.total - pot2.total</code> is a mistake as your function should returns only 1,0 or -1. Commented Nov 16, 2009 at 15:05

3 Answers 3

9

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).

Sign up to request clarification or add additional context in comments.

1 Comment

He wants to sort descending, so reverse=True.
2

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))

Comments

1

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

2 Comments

if you want to do that, just call -cmp(pot1.total, pot2.total).
just returning 1 or -1 makes the difference ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.