Sorting list of objects on arbitrary attribute

Max M maxm at mxm.dk
Thu Jul 18 07:58:01 EDT 2002


I often find that I need to sort a list of objects on one or more 
attributes.

So I have written a function which does this. It is listed below.

But usually when I think up something clever it is allready included in 
the standard library, or somebody has a 2 liner which does the same thing.

So what is the better solution ;-)

If something like it isn't included in the standard library, how come? 
It is a very common functionality that I have seen used in many places.


regards Max M



---------------------------------------------------

def objSort(aList, attributes):
     """
     Sorts list on one or more attributes.
     If attribute is callable it sorts on the result
     attributes can be a single attribute-name or a sequence of them
     """
     sortableList = []
     if type(attributes) == type(''):
         attributes = [attributes]
     for item in aList:
         sortList = []
         for attrName in attributes:
             attr = getattr(item, attrName)
             if callable(attr):
                 attr = attr()
             sortList.append(attr)
         sortList.append(item)
         sortableList.append(tuple(sortList))
     sortableList.sort()
     return [tup[-1] for tup in sortableList]



if __name__ == '__main__':

     #############################
     ## Simple tests

     from random import choice, randrange

     class Struct:

         # simple test object

         def __init__(self, **kw):
             self.__dict__ = kw
             self.rand = randrange(20,25)

         def __str__(self):
             result = []
             for key, val in self.__dict__.items():
                 result.append('%s: %s\n' % (key, val))

             return ''.join(result)

         def rndNumber(self):
             return self.rand

     randomLikeStrings = [
         'sdf asdf asdf asdf i',
         'sdf asdf asdf asdf h',
         'sdf asdf asdf asdf g',
         'sdf asdf asdf asdf f',
         'sdf asdf asdf asdf e',
         'sdf asdf asdf asdf d',
         'sdf asdf asdf asdf c',
         'sdf asdf asdf asdf b',
         'sdf asdf asdf asdf a',
         ]

     # build up a list of objects to sort.

     listSize = 30
     aList = []
     for i in range(listSize):
         aList.append(
             Struct(
                 name=choice(randomLikeStrings),
                 age=randrange(1, 5)
             )
         )

     # Sort and print out

     aList = objSort(aList, ('name', 'age', 'rndNumber'))
     for item in aList:
         print item





More information about the Python-list mailing list