List sorting with multiple attributes and mixed order

I have to sort a list with multiple attributes. I can do that in ascending order for ALL attributes easily with

L.sort(key=operator.attrgetter(attribute))....

but the problem is, that I have to use mixed configurations for ascending/descending… I have to “imitate” a bit the SQL Order By where you can do something like name ASC, year DESC.
Is there a way to do this easily in Python without having to implement a custom compare function?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

If your attributes are numeric, you have this.

def mixed_order( a ):
    return ( a.attribute1, -a.attribute2 )

someList.sort( key=mixed_order )

If your attributes includes strings or other more complex objects, you have some choices.

The .sort() method is stable: you can do multiple passes. This is perhaps the simplest. It’s also remarkably fast.

def key1( a ): return a.attribute1
def key2( a ): return a.attribute2

someList.sort( key=key2, reverse=True )
someList.sort( key=key1 )

If this is the only sort, you can define your own special-purpose comparison operators. Minimally, you need __eq__ and __lt__. The other four can be derived from these two by simple logic.

Method 2

A custom function will render your code more readable. If you have many sorting operations and you don’t want to create those functions though, you can use lambda’s:

L.sort(lambda x, y: cmp(x.name, y.name) or -cmp(x.year, y.year))

Method 3

You can’t, but writing the compare function is easy:

def my_cmp(a, b):
    return cmp(a.foo, b.foo) or cmp(b.bar, a.bar)
L.sort(my_cmp)


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x