Reputation: 387
I have searched lot of time for this. I have got some idea about sorting using key parameter.
I have a list of tuple like this. It's got by OpenCV Hough Circle detection.
correctC = [(298, 172, 25), (210, 172, 25), (470, 172, 25), (386, 172, 22), (648, 172, 25), (384, 44, 22), (558, 110, 22), (562, 170, 25), (382, 108, 25), (734, 172, 25), (126, 172, 24), (646, 44, 22), (296, 110, 23), (126, 234, 26), (470, 236, 25), (296, 44, 25), (208, 108, 24), (38, 170, 25), (730, 110, 22), (730, 44, 25), (468, 110, 23), (468, 44, 25), (208, 44, 25), (124, 44, 22), (558, 44, 22), (36, 110, 24), (36, 44, 22), (298, 234, 26), (210, 236, 25), (648, 234, 25), (732, 234, 22), (562, 234, 26), (384, 236, 25), (38, 234, 26), (646, 110, 25), (124, 112, 27)]
It has 3 values. center coordinate(x,y) and radius.
I need to sort all tuples using it's x and y value.
I can do this sorting separately.
xS=sorted(correctC,key=lambda correctC: correctC[0])
This is sort according to x value only.
yS=sorted(correctC,key=lambda correctC: correctC[1])
This is sort according to y value only.
How can I do both(according to x value and y value) using one expression?
I'm using Python 2.7
Upvotes: 7
Views: 13987
Reputation: 1044
You can solve this problem writing a lambda function for you or using built-in itemgetter() offered by python
Solution - 01:
sorted_correctC = sorted(correctC, key = lambda x : x[0:2])
print(sorted_correctC)
Solution - 02
from operator import itemgetter
sorted_correctC2 = sorted(correctC, key = itemgetter(0,1))
print(sorted_correctC2)
Upvotes: 0
Reputation:
For anyone confused by the combination of
It looks like the OP wanted something like this:
sortedC = sorted(correctC)
for index in range(0, len(sortedC), 4):
sortedC[index:index + 4] = sorted(sortedC[index:index + 4], key=lambda x: x[1])
The second column of tuples shows the expected output (which should have been included in the question):
0 ( 36, 44, 22) ( 36, 44, 22)
1 ( 36, 110, 24) ( 36, 110, 24)
2 ( 38, 170, 25) ( 38, 170, 25)
3 ( 38, 234, 26) ( 38, 234, 26)
4 (124, 44, 22) (124, 44, 22)
5 (124, 112, 27) (124, 112, 27)
6 (126, 172, 24) (126, 172, 24)
7 (126, 234, 26) (126, 234, 26)
8 (208, 44, 25) (208, 44, 25)
9 (208, 108, 24) (208, 108, 24)
10 (210, 172, 25) (210, 172, 25)
11 (210, 236, 25) (210, 236, 25)
12 (296, 44, 25) (296, 44, 25)
13 (296, 110, 23) (296, 110, 23)
14 (298, 172, 25) (298, 172, 25)
15 (298, 234, 26) (298, 234, 26)
16 (382, 108, 25) (384, 44, 22) True
17 (384, 44, 22) (382, 108, 25) True
18 (384, 236, 25) (386, 172, 22) True
19 (386, 172, 22) (384, 236, 25) True
20 (468, 44, 25) (468, 44, 25)
21 (468, 110, 23) (468, 110, 23)
22 (470, 172, 25) (470, 172, 25)
23 (470, 236, 25) (470, 236, 25)
24 (558, 44, 22) (558, 44, 22)
25 (558, 110, 22) (558, 110, 22)
26 (562, 170, 25) (562, 170, 25)
27 (562, 234, 26) (562, 234, 26)
28 (646, 44, 22) (646, 44, 22)
29 (646, 110, 25) (646, 110, 25)
30 (648, 172, 25) (648, 172, 25)
31 (648, 234, 25) (648, 234, 25)
32 (730, 44, 25) (730, 44, 25)
33 (730, 110, 22) (730, 110, 22)
34 (732, 234, 22) (734, 172, 25) True
35 (734, 172, 25) (732, 234, 22) True
Where there is a True
in the fourth column, the expected output differs from sorted(correctC)
.
Upvotes: 4
Reputation:
Assuming that you want to sort by distance from the origin, this is what you want:
import math
sortedC = sorted(correctC,
cmp=lambda lhs, rhs: cmp(math.sqrt(lhs[0] ** 2 + lhs[1] ** 2),
math.sqrt(rhs[0] ** 2 + rhs[1] ** 2)))
Upvotes: 2
Reputation: 3954
In this particular case, if you don't care about how the points with equal x, y
value are arranged, just calling sort
will do the job. Tuples are sorted in lexicographic order.
correctC.sort()
If you want to be more explicit, just do as the other answer tells:
correctC.sort(key=lambda t: (t[0], t[1]))
Upvotes: 7
Reputation: 83527
Why do you need to provide a key at all? Tuples are sorted lexicographically ("dictionary order")by default. The first elements will be compared. If they are the same, then the second elements of each tuple will be compared, and so on. meaning that the first element is compared and if they are the same, then go to the next element (basically "dictionary ordering"). If you rely on this, you will get exactly what you want, other than if two circles have the same center, then they will also be sorted by radius.
Upvotes: 2
Reputation: 2246
From what I can see, this helps:
sorted(correctC, key=lambda correctC:[correctC[0],correctC[1]])
Sorted result:
[(36, 44, 22), (36, 110, 24), (38, 170, 25), (38, 234, 26), (124, 44, 22), (124, 112, 27), (126, 172, 24), (126, 234, 26), (208, 44, 25), (208, 108, 24), (210, 172, 25), (210, 236, 25), (296, 44, 25), (296, 110, 23), (298, 172, 25), (298, 234, 26), (382, 108, 25), (384, 44, 22), (384, 236, 25), (386, 172, 22), (468, 44, 25), (468, 110, 23), (470, 172, 25), (470, 236, 25), (558, 44, 22), (558, 110, 22), (562, 170, 25), (562, 234, 26), (646, 44, 22), (646, 110, 25), (648, 172, 25), (648, 234, 25), (730, 44, 25), (730, 110, 22), (732, 234, 22), (734, 172, 25)]
Upvotes: 4