1

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))
1
  • This function would never return 1? That doesn't seem quite right for a sort callback. Commented Mar 29, 2020 at 8:33

1 Answer 1

2
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

Sign up to request clarification or add additional context in comments.

7 Comments

start should come before end; that doesn't seem to be considered here?
What is the priority order, is it 0>1>2, the numbers denoting the indices.
also, for [2] == 'start', then [1] is descending, otherwise it's ascending.
Probably this will fix it: (x[0], x[2] == 'end', -x[1] if x[2] == 'start' else x[1])
points.sort(key = lambda x: (x[0], x[2] == 'end', -x[1] if x[2] == 'start' else x[1])) Yes this seems to work, I'll update my answer, thanks.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.