[Tutor] sorting objects in lists by 2 attr

Kent Johnson kent37 at tds.net
Tue Jul 24 13:48:54 CEST 2007


Philippe Niquille wrote:
> Tanks a mill!
> 
> I don't know why I searched so far..
> 
> Anyway, I wrapped the django custom SQL call and built a nice dictionary 
> out of the resulting rows (which is similar to querysets). 
> See http://www.djangosnippets.org/snippets/207/ 
> <http://www.djangosnippets.org/snippets/207/> for details.

That code could be much simpler. You wrote,

     fdicts = []
     for row in rows:
         i = 0
         cur_row = {}
         for key in qkeys:
             cur_row[key] = row[i]
             i = i+1
         fdicts.append(cur_row)

So qkeys is a list of names for the values in each row. You can convert 
the list of names and row into a dict with
   cur_row = dict(zip(qkeys, row))

zip(qkeys, row) converts the two list into a list of key, value pairs 
which can be used directly to create the dict.

This is simple enough to use in a list comprehension, so the outer loop 
can be written as

fdicts = [ dict(zip(qkeys, row)) for row in rows ]


To answer your original question, the best way to sort on multiple 
attributes is to make a key function that returns a tuple of the desired 
attributes and provide that to sort. In Python 2.5, the function 
operator.attrgetter() will create the key function for you, so you can write
   import operator
   newscore.sort(key=operator.attrgetter('score', 'owner'))
or whatever the correct attributes are.

In older Python attrgetter only takes a single argument so you have to 
create the key function yourself:
   def key_func(item):
     return (item.score, item.owner)
   newscore.sort(key=key_func)

Kent


More information about the Tutor mailing list