Sushim Mukul Dutta Sushim Mukul Dutta - 1 year ago 154
Python Question

Python: using custom comparator for sort in dict

I have a dictionary which has the following content :

dict = {'P1' :361 , 'P2' : 361, 'P3' : 391, 'P6' : 361, 'P4':361, 'P5' :361}

which needs to be sorted on basis of value in descending order. For any given item if the value is same to the item it is compared, it is to be sorted on the ascending order of key. Hence, the resultant value of the dict should be this.

{'P3' : 391 , 'P1' : 361, 'P2': 361, 'P4': 361, 'P5': 361,'P6' : 361}

I have achieved the first part using this :

sorted_dict = OrderedDict(sorted(dict.items(), key=lambda t: t[1],reverse=True))

However, I am uncertain how to go beyond that. I am assuming the comparator function typically can be something like this

def comparator(item1,item2):
if item1.value() == item2.value():
if item1.key()<item2.key():
return -1
if item1.key()>item2.key():
return 1
if item1.key() == item2.key():
return 0
if item1.value() < item2.value():
return -1
if item1.value() > item2.value():
return 1

I am unsure of how to implement this. Pardon my nativity, I am beginner in Python, have very less knowledge of the programming constructs in the language. Would be great any one can refer me to the docs of whatever helps me achieve this.

Answer Source

You can just use a slightly different lambda expression as the key for sorting.

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


OrderedDict([('P3', 391), ('P1', 361), ('P2', 361), ('P4', 361), ('P5', 361), ('P6', 361)])

Supplying a key is supplying a function to transform each item before comparison. So here, the anonymous lambda function supplies a sequence transformation used for sorting - sequences are sorted by comparing each element in turn. So we sort by the negative of the number (to invert the natural ascending -> descending), and should that compare equal we move on to the string for sorting, which sorts normally the way you intend it to.