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?
Python does not guarantee that the sort() function will work if a list contains items of different data types. As long as the items can be compared using the < comparison operator, an attempt will be made to sort the list. Otherwise, an error or exception may be generated.
sort() function to sort a collection of objects (using some attribute) in Python. This function sorts the list in-place and produces a stable sort. It accepts two optional keyword-only arguments: key and reverse. The key argument specifies a single-arg function to extract a comparison key from each list object.
The sorted() function returns a sorted list of the specific iterable object. The sort() method sorts the list. 2. It sorts the list in ascending order by default.
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.
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))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With