I have constructed a list [[13, "b"], [10, "b"], [10, "a",], [4,"c"], [1, "d"]]
which is sorted by the first value in the list of two elements. That is the part I can do. What I don't know is if two elements are the same, then I want to sort it alphabetically. The method I used to sort the first list was reversing a sorted list by the first element. This however makes [10, "b"]
come before [10, "a"]
but i want "a" before "b". Is there a way to write sort by first element in descending order and if a tie, sort alphabetically by the second element?
This works:
>>> li=[[13, "b"], [10, "b"], [10, "a",], [4,"c"], [1, "d"]]
>>> sorted(li,key=lambda sl: (-sl[0],sl[1]))
[[13, 'b'], [10, 'a'], [10, 'b'], [4, 'c'], [1, 'd']]
The sorted function produces a new list. You can also sort the list in place using the sort method:
>>> li=[[13, "b"], [10, "b"], [10, "a",], [4,"c"], [1, "d"]]
>>> li.sort(key=lambda sl: (-sl[0],sl[1]))
>>> li
[[13, 'b'], [10, 'a'], [10, 'b'], [4, 'c'], [1, 'd']]
You can also do a nested sort (or sort on one key, then the second key) since python uses a stable sort:
>>> from operator import itemgetter
>>> li=[[13, "b"], [10, "b"], [10, "a",], [4,"c"], [1, "d"]]
>>> li.sort(key=itemgetter(1))
>>> li
[[10, 'a'], [13, 'b'], [10, 'b'], [4, 'c'], [1, 'd']]
>>> li.sort(key=itemgetter(0),reverse=True)
>>> li
[[13, 'b'], [10, 'a'], [10, 'b'], [4, 'c'], [1, 'd']]
Since there is no need for a lambda in a one element sort, I used the faster operator.itemgetter vs a lambda. Whether two faster sorts are faster than one, I don't know... You can also use a lambda for this method.
There is a great sort tutorial that shows many of these idioms.
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