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.