Isan Sahoo
Isan Sahoo

Reputation: 404

Sorting python list of lists with custom comparator

I'm trying to sort the below list of list:

points = [[1, 4, 'start'], [1, 6, 'start'], [2, 8, 'end'], [2, 5, 'end'], [3, 4, 'end'], [3, 9, 'start']]

Expected output:

[[1, 6, 'start'], [1, 4, 'start'], [2, 5, 'end'], [2, 8, 'end'], [3, 9, 'start'], [3, 4, 'end']]

Conditions for sorting are:

  1. If p1[0] == p2[0] and p1[2] == 'start' and p2[2] == 'start', then p1[1] or p2[1] with greater value should come first.

  2. If p1[0] == p2[0] and p1[2] == 'end' and p2[2] == 'end', then p1[1] or p2[1] with lesser value should come first.

  3. If p1[0] == p2[0] and p1[2] == 'start' and p2[2] == 'end', then point with 'start' should come first.

I tried to write a custom comparator (getting correct answer), just wondering is this the right approach? Can it be more simpler?

def mycmp(p1, p2):
    if p1[0] < p2[0]:
        return -1

    if p1[0] == p2[0]:
        if p1[2] == 'start' and p2[2] == 'start' and p1[1] > p2[1]:
            return -1
        elif p1[2] == 'end' and p2[2] == 'end' and p1[1] < p2[1]:
            return -1
        elif p1[2] == 'start' and p2[2] == 'end':
            return -1
    return 0

points.sort(key=cmp_to_key(mycmp))

Upvotes: 1

Views: 431

Answers (1)

Suraj
Suraj

Reputation: 2477

points.sort(key = lambda x: (x[0], x[2] == 'end', -x[1] if x[2] == 'start' else x[1]))

Can you use lambda, the key is to specify the priorities in order, thanks to @Jack.

Used totally 3 keys inside the lambda function.

You first sort on x[0] in ascending order,

In case there is a tie there, you give high priority to x[2] = end

And finally you sort x[1] in descending order if x[2]=start and ascending if x[2]=end

Logic is to specify your priorities in order inside the lambda function

Upvotes: 2

Related Questions