Home > OS >  Sorting dictionary by value in python under multiple constraints
Sorting dictionary by value in python under multiple constraints

Time:07-18

Consider the dictionary below: Let's call it hmap
This is a dictionary where they key is of type int and the values are tuples

{1: (80, 40, 120), 2: (60, 20, 80), 3: (80, 50, 130), 4: (60, 90, 150), 5: (70, 90, 160), 6: (70, 80, 150)}

To sort the dictionary by value in reverse order; something like the following can be done.
For example:

mm = {k:v for k, v in sorted(hmap.items(), key=lambda x:x[1], reverse=True)}

The sorted O/P is as follows:

{3: (80, 50, 130), 1: (80, 40, 120), 5: (70, 90, 160), 6: (70, 80, 150), 4: (60, 90, 150), 2: (60, 20, 80)}

Since I am sorting the dict by value, it defaults to sorting by the first value in the tuple.

Please consider the following scenario's:

  1. What's the best approach to sorting the dict by second (or) third value in the tuple?
  2. Likewise, what if I would like to sort by the second value in the tuple; yet if there is a tie, I would like to sort them in the ascending order of the key value?

In scenario 2, Consider hmap to be:

{1: (80, 40, 120), 2: (60, 20, 80), 3: (80, 50, 130)}

Here if we sort this by first value of the tuple in reverse; there would be a tie; since 80 is found in both key 1 and key 3.

What's the best way to sort by the first value in the tuple, while giving ascending order of priority to the key value incase of a tie?

CodePudding user response:

  1. Tell key to ignore the first element using slicing to create a new tuple without the first element:

    dict(sorted(hmap.items(), key=lambda x: x[1][1:], reverse=True))
    

    outputs

    {
        5: (70, 90, 160),
        4: (60, 90, 150),
        6: (70, 80, 150),
        3: (80, 50, 130),
        1: (80, 40, 120),
        2: (60, 20, 80)
    }
    

  1. Manually specify the condition inside the lambda by building the tuple with a minus sign before the value of the key (x[0] in this case):

    dict(sorted(hmap.items(), key=lambda x: (x[1][0], -x[0]), reverse=True))
    

    outputs

    {
        1: (80, 40, 120),
        3: (80, 50, 130),
        5: (70, 90, 160),
        6: (70, 80, 150),
        2: (60, 20, 80),
        4: (60, 90, 150)
    }
    
  • Related