Home > Enterprise >  Sorting a dictionary with values as tuple
Sorting a dictionary with values as tuple

Time:07-25

I have a dictionary as follows and I want to sort this based on the last element of the tuple in a non-increasing manner. However, if two or more of the last elements are the same, then they should be sorted based on the second element.

    capacity= {
    'one': (57000, 3100, 0.12903225806451613),
 'two': (52911, 2400, 0.125),
 'three': (48200, 2400, 0.125),
 'four': (48200, 2480, 0.125),
 'five': (11464, 1200, 0.20833333333333334),
 'six': (44000, 1172, 0.21331058020477817),
 'seven': (42000, 1172, 0.21331058020477817)}

After sorting by the third element of the tuple I get the following results.

sorted_capacity={k: (v1,v2,v3) for k, (v1,v2,v3) in sorted(capacity.items(), key=lambda x: x[1][2],reverse=True)}



sorted_capacity

{'six': (44000, 1172, 0.21331058020477817),
 'seven': (42000, 1172, 0.21331058020477817),
 'five': (11464, 1200, 0.20833333333333334),
 'one': (57000, 3100, 0.12903225806451613),
 'two': (52911, 2400, 0.125),
 'three': (48200, 2400, 0.125),
 'four': (48200, 2480, 0.125)}

However, as I mentioned before, I need to have 'four': (48200, 2480, 0.125)} before 'two': (52911, 2400, 0.125), because 2480 is higher than 2400. Basically my output should be like this:

sorted_capacity

    {'six': (44000, 1172, 0.21331058020477817),
     'seven': (42000, 1172, 0.21331058020477817),
     'five': (11464, 1200, 0.20833333333333334),
     'one': (57000, 3100, 0.12903225806451613),
     'four': (48200, 2480, 0.125),
     'two': (52911, 2400, 0.125),
     'three': (48200, 2400, 0.125)
     }

Can anyone help me figure out how to achieve this?

CodePudding user response:

In the key function, you can reverse the tuples to compare:

>>> dict(sorted(capacity.items(), key=lambda item: item[1][::-1], reverse=True))
{'six': (44000, 1172, 0.21331058020477817),
 'seven': (42000, 1172, 0.21331058020477817),
 'five': (11464, 1200, 0.20833333333333334),
 'one': (57000, 3100, 0.12903225806451613),
 'four': (48200, 2480, 0.125),
 'two': (52911, 2400, 0.125),
 'three': (48200, 2400, 0.125)}

CodePudding user response:

Your code with the issue fixed:

from pprint import pprint

capacity = {
    'one': (57000, 3100, 0.12903225806451613),
    'two': (52911, 2400, 0.125),
    'three': (48200, 2400, 0.125),
    'four': (48200, 2480, 0.125),
    'five': (11464, 1200, 0.20833333333333334),
    'six': (44000, 1172, 0.21331058020477817),
    'seven': (42000, 1172, 0.21331058020477817)}

sorted_capacity = {
    k: (v1, v2, v3)
    for k, (v1, v2, v3) in sorted(capacity.items(), key=lambda x: (x[1][2], x[1][1]), reverse=True)
}

pprint(sorted_capacity, sort_dicts=False)  # don't want pprint to sort again

This just adds the middle column to the sorting key. If you want the first column to be used when the second is also identical, you could also just reverse the tuple:

key=lambda x: tuple(reversed(x[1]))

Or:

key=lambda x: x[1][::-1]

CodePudding user response:

Use

key = lambda x: (x[1][-1], x[1][1])

This compares tuples of the last and second elements in each tuple. Since tuples are ordered lexicographically, this produces the ordering you want.

  • Related