36

I'd like to use the somelist.sort() method to do this if possible.

I have a list containing objects, all objects have a member variable resultType that is an integer. I'd like to sort the list using this number.

How do I do this?

Thanks!

4 Answers 4

74
somelist.sort(key = lambda x: x.resultType)

Here's another way to do the same thing that you will often see used:

import operator
s.sort(key = operator.attrgetter('resultType'))

You might also want to look at sorted if you haven't seen it already. It doesn't modify the original list - it returns a new sorted list.

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

2 Comments

You answered two of my questions (attrgetter..) and pointed me to something useful. Thanks!
You helped me realise how sorted differs from sort! Thanks
11

Of course, it doesn't have to be a lambda. Any function passed in, such as the below one, will work

def numeric_compare(x, y):
   if x > y:
      return 1
   elif x == y:
      return 0
   else:  #x < y
      return -1

a = [5, 2, 3, 1, 4]
a.sort(numeric_compare)

Source : Python Sorting

So, in your case ...

def object_compare(x, y):
   if x.resultType > y.resultType:
      return 1
   elif x.resultType == y.resultType:
      return 0
   else:  #x.resultType < y.resultType
      return -1

a.sort(object_compare)

The aforementioned lambda is definitely the most compact way of doing it, but there's also using operator.itemgetter.

import operator
#L = [('c', 2), ('d', 1), ('a', 4), ('b', 3)]
map(operator.itemgetter(0), L)
#['c', 'd', 'a', 'b']
map(operator.itemgetter(1), L)
#[2, 1, 4, 3]
sorted(L, key=operator.itemgetter(1))
#[('d', 1), ('c', 2), ('b', 3), ('a', 4)]

So you'd use itemgetter('resultType'). (Assuming getitem is defined.)

sorted(L, key=operator.itemgetter('resultType'))

2 Comments

cmp is deprecated - doesn't even exist in Python3. You should use a key function instead.
Thank you for this. I always like seeing non-lambda ways to do things, even if I will ultimately use the lambda version (it just feels sexier)
1
somelist.sort(cmp = lambda x, y: cmp(x.resultType, y.resultType))

Is better than:

somelist.sort(key = lambda x: x.resultType)

In the first case we pass in a comparison function which is used to pair-wise compare the elements in the list. In the second case we allocate a new list of pairs of the result of the key function, and the original value. Then we sort that list, then strip off the key values from the pairs. This is really useful if your comparison function is expensive, but is just a waste of memory if the comparison is really cheap.

That is, the expansion of the key version looks something like this:

l = [y for x,y in sorted(zip([key(i) for i in l], l))]

For a simple key function, that is clearly too much overhead, so instead I would suggest using the lighter function based sort.

Note that the cmp function parameter needs to return -1, 0, 1 in the less than, equal and greater than cases. You could write that yourself, but you can also use the built in cmp function which is clearer.

1 Comment

Sigh, thanks @gnibbler, I didn't know that the cmp param had been deprecated in Python 3, that's good to know. But if you're in python 2.x, I think it's clearer and more efficient than the key version. In Python 3, I'd follow Mark Byers.
0

For Python 3.x, a user has to provide a key function. Source

def cmp_to_key(mycmp):
'Convert a cmp= function into a key= function'
class K(object):
    def __init__(self, obj, *args):
        self.obj = obj
    def __lt__(self, other):
        return mycmp(self.obj, other.obj) < 0
    def __gt__(self, other):
        return mycmp(self.obj, other.obj) > 0
    def __eq__(self, other):
        return mycmp(self.obj, other.obj) == 0
    def __le__(self, other):
        return mycmp(self.obj, other.obj) <= 0
    def __ge__(self, other):
        return mycmp(self.obj, other.obj) >= 0
    def __ne__(self, other):
        return mycmp(self.obj, other.obj) != 0
return K
>>> sorted([5, 2, 4, 1, 3], key=cmp_to_key(reverse_numeric))
[5, 4, 3, 2, 1]

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.