Python sorting – A list of objects

Question:

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!

Asked By: Art

||

Answers:

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.

Answered By: Mark Byers

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'))
Answered By: Rizwan Kassim
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.

Answered By: Dan McCormick

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]
Answered By: bigdata2
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.