Jython/Sikulix: Tupel sortieren
Wenns hier nicht passt, bitte Verweis auf passende Gruppe. Ich spiel hier bisserl mit Sikulix/Jython und Bilderkennung herum und werde gerade mit Python warm (mach sonst Altsprachen und Java). Problem ist eine Liste von Tupel zu sortieren bzw. der Zugriff darauf. Von Sikulix bekomme ich einen Iterator auf gefundene Objekten die ich wahlweise nach Score oder einer auszurechnenden Distanz zur Mitte sortieren möchte. iter = region.findAll(patTarget[0]) lstTarget = list(iter) tupTarget = [Match, 0, 0] * len(lstTarget) for i in range(len(lstTarget)): match = lstTarget[i] tupTarget[i] = (match, match.getScore(), calcdistance(match, center)) Bis hier ists noch heile (zumindest motzt der Interpreter nicht). Die 2 Fragen sind: wie sortiere ich das nun nach Element 1(Score, float) oder 2 (Distance, int) und wie komme ich dann wieder an 0/1/2 der Liste von Tupeln ran? "print tupTarget[idx][2]" geht nicht. Bernd
Bernd Hohmann, 30.12.2013 15:01:
Wenns hier nicht passt, bitte Verweis auf passende Gruppe. Ich spiel hier bisserl mit Sikulix/Jython und Bilderkennung herum und werde gerade mit Python warm (mach sonst Altsprachen und Java).
Na dann willkommen!
Problem ist eine Liste von Tupel zu sortieren bzw. der Zugriff darauf.
Von Sikulix bekomme ich einen Iterator auf gefundene Objekten die ich wahlweise nach Score oder einer auszurechnenden Distanz zur Mitte sortieren möchte.
iter = region.findAll(patTarget[0]) lstTarget = list(iter) tupTarget = [Match, 0, 0] * len(lstTarget) for i in range(len(lstTarget)): match = lstTarget[i] tupTarget[i] = (match, match.getScore(), calcdistance(match, center))
Das ist recht holpriger (lies: unidiomatischer) Code. Gängiger wäre eine List-Comprehension, also sowas hier: target = [ (match, match.getScore(), calcdistance(match, center)) for match in region.findAll(patTarget[0]) ] Die Idee ist, dass eine Schleife abgelaufen wird und dabei eine neue List entsteht. Die Werte für die Listeneinträge sind die, die du vor das "for" schreibst, also hier das Tupel. Ob so etwas generisches wie "target" ein guter Name ist, musst du dir selbst überlegen. Das hängt vom Kontext ab.
Bis hier ists noch heile (zumindest motzt der Interpreter nicht).
Die 2 Fragen sind: wie sortiere ich das nun nach Element 1(Score, float) oder 2 (Distance, int)
from operator import itemgetter target.sort(key=itemgetter(1)) # Tupelposition 1: Score target.sort(key=itemgetter(2)) # Tupelposition 2: Distance
und wie komme ich dann wieder an 0/1/2 der Liste von Tupeln ran? "print tupTarget[idx][2]" geht nicht.
Sieht jetzt erstmal nicht falsch aus. "Geht nicht" heißt genau was? Bekommst du eine Fehlermeldung? Und wenn ja, welche? Ab Python 2.7 kannst du auch ein "namedtuple" verwenden, dabei kannst du jedem Eintrag einen Namen geben. Siehe "collections" Modul. Ob deine Jython-Version das schon kann, weiß ich aber nicht. Stefan
wenn du score und die distance noch öfter brauchst, bietet sich das hier an: targets = [] for match in region.findAll(patTarget[0]): targets.append(( match, match.getScore(), calcdistance(match, center) )) targets.sort(key=lambda x: x[1]) # target ist jetzt nach dem ersten element sortiert sorted_target = sorted(targets, key=lambda x: x[2]) # targets ist immer noch nach dem ersten element sortiert, # sorted_target aber nach dem zweiten element. wenn du die nur zum sortieren brauchst geht es noch ein wenig kompakter: sorted_targets = sorted( region.findAll(patTarget[0]), key=lambda target: target.getScore() ) dokumentation: http://docs.python.org/3/library/stdtypes.html?highlight=sort#list.sort weitere informationen: https://wiki.python.org/moin/HowTo/Sorting/ eigentlich sollte man auf tupel ganz normal zugreifen können:
a = [(1,2),(3,4)] a[1][1] 4
schöne grüße
Hallo Bernd, Am 30.12.2013 15:01, schrieb Bernd Hohmann:
Die 2 Fragen sind: wie sortiere ich das nun nach Element 1(Score, float) oder 2 (Distance, int) und wie komme ich dann wieder an 0/1/2 der Liste von Tupeln ran? "print tupTarget[idx][2]" geht nicht.
zum Thema Sortieren in Python habe ich vor längerer Zeit mal ein kleines Tutorial geschrieben: http://wiki.python-forum.de/Sortierungs-Tutorium TL;DR: Benutze das Decorate-Sort-Undecorate Pattern durch das 'key'-Argument für .sort()/sorted() mit operator.itemgetter()/.attrgetter() oder einem lambda-Ausdruck. Chris
participants (4)
-
83a
-
Bernd Hohmann
-
Christopher Arndt
-
Stefan Behnel