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.

4

4 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.)

4

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

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy