1

I am trying to sort a dictionary, the order which I want to follow is that first, the dictionary should be sorted in increasing order by values and if the values for two or more keys are equal then I want to sort the dictionary by the keys in descending order.

Here is the code:

dictionary = {0: 150, 1: 151, 2: 150, 3: 101, 4: 107}
print(sorted(dictionary.items(), key=lambda x: (x[1], x[0])))

I want the output to be the following: [(3, 101), (4, 107), (2, 150), (0, 150), (1, 151)]

But the output is: [(3, 101), (4, 107), (0, 150), (2, 150), (1, 151)]

Sherlock
  • 129
  • 1
  • 1
  • 9
  • 3
    Given that the values are numeric, you can use `sorted(dictionary.items(), key=lambda x: (-x[1], x[0]))` – alani Aug 21 '20 at 06:58
  • If you want the two values to simultaneously be sorted in opposite directions, you'll have to make one of them *negative*. – jonrsharpe Aug 21 '20 at 06:58
  • @jonrsharpe Any generic suggestions for how if neither are numeric? (All I could think of previously was writing a combined `cmp` function along the lines of `cmp1 or cmp2` and using `cmp_to_key`.) – alani Aug 21 '20 at 06:59
  • What I wrote above is the opposite of what was asked for (although the general principle holds) - corrected in my answer below. – alani Aug 21 '20 at 07:12
  • Here, you're using sorted() which takes ascending order as default value – Sanmitha Sadhishkumar Aug 21 '20 at 07:42
  • Isn't the question worth upvoting? – Sherlock Aug 21 '20 at 16:54
  • @Sherlock It is a reasonable question, and on this occasion okay yes I will upvote it. *However*, soliciting votes is not really a good habit. Fundamentally, you ask a question because you would like to have it answered, rather than to earn points from it. – alani Aug 21 '20 at 20:15
  • It's not at all about points, It's about that genuine questions deserve appreciation/criticism which is kind of feedback for the OP. – Sherlock Aug 22 '20 at 07:47

1 Answers1

1

Because the values are numeric here, you can use negation as having the same effect as reversing the sort order:

sorted(dictionary.items(), key=lambda x: (x[1], -x[0]))

For the more generic case where you can't rely on the values being numeric, here is a possible approach, although there may be a better way.

from functools import cmp_to_key

def cmp(a, b):
    # https://stackoverflow.com/a/22490617/13596037
    return (a > b) - (a < b)

def cmp_items(a, b):
    """
    compare by second item forward, or if they are the same then use first item
    in reverse direction (returns -1/0/1)
    """
    return cmp(a[1], b[1]) or cmp(b[0], a[0])

dictionary = {0: 150, 1: 151, 2: 150, 3: 101, 4: 107}

print(sorted(dictionary.items(), key=cmp_to_key(cmp_items)))
alani
  • 12,573
  • 2
  • 13
  • 23