The proper idiom for sorting objects in a list by an arbitrary property

Alex Martelli aleax at aleax.it
Tue Sep 11 09:03:44 EDT 2001


"Max Møller Rasmussen" <maxm at normik.dk> wrote in message
news:mailman.1000206494.6423.python-list at python.org...
> I have written the below function to sort objects by an arbitrary
property.
> But I wonder if there is a better way to do it?

There's only one possible, minor enhancement, IF you don't
care about the sort being stable (yours is...):

> def sort(objects, sortAttrib):
>
>     # Sorts a list of objects in accordance to an attribute of choice
>     # I assume that Pythons built in sort() is blistering fast
>     # So I run around hoops to use that.

And well indeed you do -- the decorate-sort-undecorate idiom
that you use is invariably best.

>     # makes a list of tuples ('value of sortatrib', 'index of object')
>     sortValues = [
>         (getattr(objects[i], sortAttrib), i) for i in range(len(objects))
>                 ]
>     sortValues.sort(), # Sorts by first value in tuple
>     return [objects[sortTuple[1]] for sortTuple in sortValues]

The sort actually sorts by the whole tuple, so if first items
compare equal the second items (indices) will tell and your
sort will thus be a stable sort.  If you don't need that, it
might be faster (you'd better time it, though...) to do:

    sortValues = [
        (getattr(obj, sortAttrib), obj) for obj in objects
                 ]
    sortValues.sort()
    return [obj for attrib, obj in sortValues]

Don't worry, you're not copying the objects back and forth,
only references to them, so that doesn't take any more memory
or copying effort than the version using the indices:-).

This is just saving a few indexing steps, which is why I would
hope it's slightly faster -- I also think it's simplest,
which is a more important issue most of the time:-).


Alex






More information about the Python-list mailing list