So I'm working with a few pre-existing comparators that compare certain values in two tuples and return true if the first is greater than the second, false if otherwise. Here's the code for one of them:
def cmpValue(subInfo1, subInfo2): """ Returns True if value in (value, work) tuple subInfo1 is GREATER than value in (value, work) tuple in subInfo2 """ # TODO... if subInfo1[0] > subInfo2[0]: return True else: return False Now, I have a dictionary that has numerous tuple entries of the type being compared above. I want to sort them all in reverse order, but I don't really understand how I would accomplish that. I was thinking something like:
sortedDict = sorted(subjects, key=comparator, reverse = True) But I don't know what to pass into the comparator because each comparator takes two arguments (subInfo1, subInfo2). I cannot change the comparator functions.
44 Answers
You're passing the comparator as the key function. You should be passing it as the cmp, wrapped in some kind of function that turns it into a proper comparator.
def make_comparator(less_than): def compare(x, y): if less_than(x, y): return -1 elif less_than(y, x): return 1 else: return 0 return compare sortedDict = sorted(subjects, cmp=make_comparator(cmpValue), reverse=True) (Although actually, you should be using key functions:
sorted(subjects, operator.itemgetter(0), reverse=True) Also note that sortedDict will not actually be a dict, so the name is rather confusing.)
In Python 3 there is no cmp argument for the sorted function (nor for list.sort).
According to the docs, the signature is now sorted(iterable, *, key=None, reverse=False), so you have to use a key function to do a custom sort. The docs suggest:
Use
functools.cmp_to_key()to convert an old-style cmp function to a key function.
Here's an example:
>>> def compare(x, y): ... return x[0] - y[0] ... >>> data = [(4, None), (3, None), (2, None), (1, None)] >>> from functools import cmp_to_key >>> sorted(data, key=cmp_to_key(compare)) [(1, None), (2, None), (3, None), (4, None)] However, your function doesn't conform to the old cmp function protocol either, since it returns True or False. For your specific situation you can do:
>>> your_key = cmp_to_key(make_comparator(cmpValue)) >>> sorted(data, key=your_key) [(1, None), (2, None), (3, None), (4, None)] using the make_comparator function from @Fred Foo's answer.
The answer of @kaya3 is correct. I just propose another implementation in which we can use boolean for the comparator.
class YourTupleComparator(tuple): def __lt__(self, other): return self[0] < other[0] sorted(subjects, key=YourTupleComparator) We can now use this to sort a 2-D array:
A.sort(key=lambda a: (a[0], -a[1])) This will sort the 2d-array by ascending order of A[0] and descending order of A[1].
2