Reputation: 404
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:
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.
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.
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
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