-1

I have list of lists:

unsorted_list = [[3, 'A'], [1, 'A'], [3, 'B'], [4, 'B'], [4, 'A'], [2, 'C']]

And I want to get:

sorted_list = [[4, 'A'], [4, 'B'], [3, 'A'], [3, 'B'], [2, 'C'], [1, 'A']]

List is sorted in descending order on first element. If first elements are equal then is sorted on second element but in alphabetical order (ascending)

So far I got idea to sort it like that

unsorted_list.sort(key=lambda element: (element[0], element[1]), reverse=True)

this will sort list by two elements but in descending order.

Question: Is there way to sort the list of lists by first element (in descending order), and if first elements are equal then by second element in ascending order?

Edit: First elem is always int and second is a string Thx for all the answers.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
michal w
  • 119
  • 7

2 Answers2

3

In this particular case, since first value is an integer, don't reverse, just use negative key for integer

unsorted_list = [[3, 'A'], [1, 'A'], [3, 'B'], [4, 'B'], [4, 'A'], [2, 'C']]

sorted_list = [[4, 'A'], [4, 'B'], [3, 'A'], [3, 'B'], [2, 'C'], [1, 'A']]

unsorted_list.sort(key=lambda element: (-element[0], element[1]))

print(unsorted_list====sorted_list)  # prints True
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
3

You could achieve the desired result in the specific example you gave by using .sort twice.

First to order the second elements in the inner lists:

>>> unsorted_list.sort(key=lambda element:element[1])
>>> unsorted_list
[[3, 'A'], [1, 'A'], [4, 'A'], [3, 'B'], [4, 'B'], [2, 'C']]

And secondly, to order the first elements:

>>> unsorted_list.sort(key=lambda element:element[0], reverse=True)
>>> unsorted_list
[[4, 'A'], [4, 'B'], [3, 'A'], [3, 'B'], [2, 'C'], [1, 'A']]
David Collins
  • 848
  • 3
  • 10
  • 28
  • It's performing 2 sort operations, so not very optimal, but the main advantage of this method is that it works with elements other than integers (so the negation trick cannot be used). – Jean-François Fabre May 02 '18 at 09:11
  • it's `O(n*log(n))`, done 2 times. – Jean-François Fabre May 02 '18 at 09:25
  • Well, it's `O(n log n)`, and TimSort is optimized for sorting partially sorted lists, so subsequent sorts will generally be rather quick, but it's still better if it can be done in one pass. (FWIW, when `.sort` is called with a key function the sort key is only computed once for each item to be sorted). – PM 2Ring May 02 '18 at 09:26
  • The output of the second sort seems incorrect. According to the question the expected output should be - [[4, 'A'], [3, 'A'], [1, 'A'], [4, 'B'], [3, 'B'], [2, 'C']] as we are sorting in descending for equal ones from the first sort. – Python_Novice Jul 29 '21 at 06:59