2

Here is the case, I have a list like:

[(1, a), (1, b), (5, c)]

I would like to sort the list so that it first depends on the number in descending order, then the characters in ascending order.

I tried:

sorted(theList, key = lambda x:(x[0], x[1]), reverse = True)

But the result is ordered by descending order in both the key. And apparently, reverse only take one variable I searched the web and couldn't find the solution. Please help! Thank you!

spicyShoyo
  • 343
  • 1
  • 7
  • 13
  • 6
    Are you looking for something like this? http://stackoverflow.com/questions/3979872/python-how-to-sort-a-complex-list-on-two-different-keys – idjaw Aug 27 '16 at 02:39

2 Answers2

10

If your first element in the tuple is an integer, you can sort by its negative value:

sorted(theList, key=lambda (num, letter): (-num, letter))
Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Karin
  • 8,404
  • 25
  • 34
3

According to Python documentation:

The built-in sorted() function is guaranteed to be stable. A sort is stable if it guarantees not to change the relative order of elements that compare equal — this is helpful for sorting in multiple passes (for example, sort by department, then by salary grade).

Therefore, an easy way to do it will be doing a two-pass sorting:

sorted(theList, key = lambda x:x[1])
sorted(theList, key = lambda x:x[0], reverse = True)

Or if you really want a one-liner, you can do this:

sorted(thisList, key = lambda x:x[0] * 26 - (ord(x[1]) - ord('a')), reverse = True)

This one-liner assumes that all the characters are lowercase. What it does is that it makes each two consecutive numbers have a step of 26 instead of 1, and the characters a-z are mapped to 0-25, as a finer step. Since the characters are ascending order, we subtract it from the scaled number value.

This one-liner is kind of a hack, since it wouldn't work if the x[1] has no range (i.e. also a number)

lnyng
  • 925
  • 6
  • 18
  • Calling sorted() on a list does not sort it in-place; I think you mean theList.sort(). Secondly, you should make it clear that the sort needs to start with the least important element first, then work up to the largest one. – Locane Jun 02 '21 at 20:59