2017-04-13 6 views
2

Ich habe viel Zeit dafür gesucht. Ich habe eine Idee über das Sortieren mit Schlüsselparameter.Python-Liste mit mehreren Schlüsseln sortieren

Ich habe eine Liste von Tupel wie folgt. Es ist durch OpenCV Hough Circle Erkennung.

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)] 

Es hat 3 Werte. Mittelpunktskoordinate (x, y) und Radius.

Ich muss alle Tupel mit seinem x- und y-Wert sortieren.

Ich kann dies separat sortieren.

xS=sorted(correctC,key=lambda correctC: correctC[0]) 

Dies wird Sortierung nach x-Wert nur.

yS=sorted(correctC,key=lambda correctC: correctC[1]) 

Dies wird Sortierung nach y Wert nur.

Wie kann ich beides tun (nach x-Wert und y-Wert) mit einem Ausdruck?

Ich verwende Python 2.7

+0

Was sind die Definitionen von weniger als, gleich und größer als für x und y? Genauer gesagt, was ist weniger (1, 2, 3) oder (2, 1, 3), oder werden sie für die Sortierung als gleich angesehen? Oder sollten Sie x und y in Polarkoordinaten umwandeln und die Länge zum Sortieren verwenden? –

+0

'correctC' ist ein schlechter Name für das Lambda-Argument, da Sie denselben Variablennamen für die Liste und ihre Elemente wiederverwenden. – user2357112

+1

Sie sollten die erwartete Ausgabe zu Ihrer Frage hinzufügen. –

Antwort

2

Von dem, was ich sehen kann, das hilft:

sorted(correctC, key=lambda correctC:[correctC[0],correctC[1]]) 

Sortierer:

[(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)] 
+2

Sauberere Möglichkeit, das Lambda zu schreiben, da OP Python 2 verwendet: 'key = Lambda (x, y, z): (x, y)'. Oder 'Lambda-Tup: tup [: 2]' für Python 3. – timgeb

+1

@timgeb Ist das nicht die Standard-Sortierreihenfolge für Tupel überhaupt? (Anders als Sie ignorieren das dritte Element.) –

+1

'correctC' ist ein schlechter Name für das Argument Lambda, da Sie den gleichen Variablennamen für die Liste und ihre Elemente wiederverwenden. (Ich sehe, dass diese Namenswahl aber von der Frage selbst kam.) – user2357112

2

Warum Sie überhaupt tun müssen, um einen Schlüssel liefern ? Tupel werden standardmäßig lexikographisch ("Wörterbuchreihenfolge") sortiert. Die ersten Elemente werden verglichen. Wenn sie gleich sind, werden die zweiten Elemente jedes Tupels verglichen und so weiter. was bedeutet, dass das erste Element verglichen wird und wenn sie gleich sind, dann gehe zum nächsten Element (im Grunde "Wörterbuchreihenfolge"). Wenn Sie sich darauf verlassen, erhalten Sie genau das, was Sie wollen, außer wenn zwei Kreise denselben Mittelpunkt haben, dann werden sie auch nach Radius sortiert.

3

In diesem speziellen Fall, wenn Sie nicht darauf achten, wie die Punkte mit x, y Wert angeordnet sind, wird nur der Aufruf sort die Aufgabe erledigen. Tupel sind in lexikographischer Reihenfolge sortiert.

correctC.sort() 

Wenn Sie mehr explizit sein, nur zu tun, wie die andere Antwort sagt:

correctC.sort(key=lambda t: (t[0], t[1])) 
1

Unter der Annahme, dass Sie mit dem Abstand vom Ursprung sortieren wollen, ist es das, was Sie wollen:

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))) 
+0

Danke ...Ich habe viele Ideen aus Ihrer Antwort. Eigentlich hatte ich die Idee, was ich nach deiner Antwort machen möchte. Eigentlich geht es nicht um Sortierung nach Entfernung ... Sie können sehen, was ich in diesem Bild wollte: https://drive.google.com/file/d/0B53F0wBGnYhdWkRiN1pNVXNXYlE/view?usp=sharing – user119o

2

Für alle, die durch die Kombination von

verwirrt
  • Unklare Frage
  • akzeptierte Antwort
  • OP user119o ‚s Kommentare

Es sieht aus wie die OP so etwas wie dies gewünscht:

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]) 

Die zweite Spalte von Tupeln zeigt die erwartete Ausgabe (was sollte wurden in die Frage einbezogen):

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 

Wenn in der vierten Spalte ein True ist, weicht die erwartete Ausgabe von sorted(correctC) ab.

Verwandte Themen