Was ist der kürzeste Weg, X mit Werten aus Y zu sortieren, um die folgende Ausgabe zu erhalten?
["a", "d", "h", "b", "c", "e", "i", "f", "g"]
Die Reihenfolge der Elemente mit gleichem “Schlüssel” spielt keine Rolle. Ich kann auf die Verwendung von zurückgreifen for Konstrukte, aber ich bin gespannt, ob es einen kürzeren Weg gibt. Irgendwelche Vorschläge?
Die Antwort von riza könnte beim Plotten von Daten nützlich sein, da zip(*sorted(zip(X, Y), key=lambda pair: pair[0])) gibt sowohl das sortierte X als auch Y sortiert mit den Werten von X zurück.
– jil
15. Mai 2014 um 12:37 Uhr
Allgemeinerer Fall (Liste Y nach einem beliebigen Schlüssel statt der Standardreihenfolge sortieren)
– Benutzer202729
1. Oktober 2020 um 8:37 Uhr
Obwohl es vielleicht nicht offensichtlich ist, ist dies genau gleichbedeutend mit sortieren Y, und Neuanordnung von X auf die gleiche Weise, wie Y sortiert wurde. Ich hatte diese beiden Fragen eine ganze Zeit lang in meinen Saves – und quälte mich darüber, weil etwas nicht ganz richtig zu sein schien – bis ich heute die Duplizierung erkannte (nachdem ich die andere bearbeitet hatte, um sie klarer zu machen und den Titel zu verbessern).
– Karl Knechtel
2. März um 5:41
Was auch immer
Kürzester Code
[x for _, x in sorted(zip(Y, X))]
Beispiel:
X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
Y = [ 0, 1, 1, 0, 1, 2, 2, 0, 1]
Z = [x for _,x in sorted(zip(Y,X))]
print(Z) # ["a", "d", "h", "b", "c", "e", "i", "f", "g"]
Allgemein gesagt
[x for _, x in sorted(zip(Y, X), key=lambda pair: pair[0])]
Erstellen Sie eine neue, sortierte list basierend auf zip verwenden sorted().
Verwenden eines Listenverständnisses Extrakt die ersten Elemente jedes Paares aus dem sortierten, gezippten list.
Weitere Informationen zum Festlegen\Verwenden der key Parameter sowie die sorted Funktion im Allgemeinen, werfen Sie einen Blick auf Das.
Dies ist richtig, aber ich füge den Hinweis hinzu, dass dies nicht unbedingt wie erwartet funktioniert, wenn Sie versuchen, mehrere Arrays nach demselben Array zu sortieren, da der zum Sortieren verwendete Schlüssel (y, x) ist. , nicht nur y. Sie sollten stattdessen verwenden [x for (y,x) in sorted(zip(Y,X), key=lambda pair: pair[0])]
– gms7777
17. Januar 2014 um 20:33 Uhr
gute Lösung! Aber es sollte so sein: Die Liste ist nach dem ersten Element der Paare geordnet, und die Comprehension extrahiert das ‘zweite’ Element der Paare.
– MasterControlProgramm
6. Oktober 2017 um 14:31 Uhr
Diese Lösung ist schlecht, wenn es um die Lagerung geht. Wann immer möglich, wird eine In-Place-Sortierung bevorzugt.
– Hassfeind
30. Juni 2019 um 16:27 Uhr
@Hatefiend interessant, könntest du auf eine Referenz verweisen, wie man das erreicht?
– RichieV
3. September 2020 um 3:18 Uhr
@RichieV Ich empfehle die Verwendung von Quicksort oder einer In-Place-Merge-Sort-Implementierung. Sobald Sie das haben, definieren Sie Ihre eigene Vergleichsfunktion, die Werte basierend auf den Indizes der Liste vergleicht Y. Das Endergebnis sollte eine Liste sein Y unberührt und Liste X in die erwartete Lösung geändert werden, ohne jemals eine temporäre Liste erstellen zu müssen.
– Hassfeind
9. September 2020 um 5:26 Uhr
Zippen Sie die beiden Listen zusammen, sortieren Sie sie und nehmen Sie dann die gewünschten Teile:
Kombiniere diese miteinander, um Folgendes zu erhalten:
[x for y, x in sorted(zip(Y, X))]
Das ist in Ordnung, wenn X ist eine Liste von straber seien Sie vorsichtig, wenn die Möglichkeit besteht, dass < ist für einige Elementpaare in nicht definiert XzB – wenn einige von ihnen waren None
– John LaRooy
23. August 2017 um 5:05 Uhr
Wenn wir versuchen, sort über ein Zip-Objekt zu verwenden, AttributeError: 'zip' object has no attribute 'sort' ist das, was ich jetzt bekomme.
– Ash Upadhyay
23. Januar 2018 um 12:57 Uhr
Sie verwenden Python 3. In Python 2 hat zip eine Liste erstellt. Jetzt erzeugt es ein iterierbares Objekt. sorted(zip(...)) sollte noch funktionieren, oder: them = list(zip(...)); them.sort()
– Ned Batchelder
23. Januar 2018 um 16:38 Uhr
Auch wenn es Ihnen nichts ausmacht, numpy-Arrays zu verwenden (oder sich bereits mit numpy-Arrays befassen …), hier ist eine weitere nette Lösung:
Für größere Arrays / Vektoren ist diese Lösung mit numpy von Vorteil!
– MasterControlProgramm
6. Oktober 2017 um 14:53 Uhr
Wenn es sich bereits um numpy-Arrays handelt, ist es einfach sortedArray1= array1[array2.argsort()]. Und das macht es auch einfach, mehrere Listen nach einer bestimmten Spalte eines 2D-Arrays zu sortieren: zB sortedArray1= array1[array2[:,2].argsort()] um array1 (das mehrere Spalten haben kann) nach den Werten in der dritten Spalte von array2 zu sortieren.
– Aaron Bramson
12. Juni 2018 um 8:50 Uhr
Absender
Die naheliegendste Lösung für mich ist die Verwendung von key Schlüsselwort arg.
Beachten Sie, dass Sie dies zu einem Einzeiler verkürzen können, wenn Sie Folgendes möchten:
>>> X.sort(key=dict(zip(X, Y)).get)
Wie Wenmin Mu und Jack Peng betont haben, setzt dies voraus, dass die Werte in X sind alle verschieden. Das geht ganz einfach mit einer Indexliste:
>>> Z = ["A", "A", "C", "C", "C", "F", "G", "H", "I"]
>>> Z_index = list(range(len(Z)))
>>> Z_index.sort(key=keydict.get)
>>> Z = [Z[i] for i in Z_index]
>>> Z
['A', 'C', 'H', 'A', 'C', 'C', 'I', 'F', 'G']
Da der von Whatang beschriebene Ansatz zum Dekorieren-Sortieren-Nicht-Dekorieren etwas einfacher ist und in allen Fällen funktioniert, ist er wahrscheinlich die meiste Zeit besser. (Dies ist eine sehr alte Antwort!)
pylang
more_itertools hat ein Tool zum parallelen Sortieren von Iterables:
Gegeben
from more_itertools import sort_together
X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
Y = [ 0, 1, 1, 0, 1, 2, 2, 0, 1]
Die Antwort von riza könnte beim Plotten von Daten nützlich sein, da zip(*sorted(zip(X, Y), key=lambda pair: pair[0])) gibt sowohl das sortierte X als auch Y sortiert mit den Werten von X zurück.
– jil
15. Mai 2014 um 12:37 Uhr
Allgemeinerer Fall (Liste Y nach einem beliebigen Schlüssel statt der Standardreihenfolge sortieren)
– Benutzer202729
1. Oktober 2020 um 8:37 Uhr
Obwohl es vielleicht nicht offensichtlich ist, ist dies genau gleichbedeutend mit sortieren Y, und Neuanordnung von X auf die gleiche Weise, wie Y sortiert wurde. Ich hatte diese beiden Fragen eine ganze Zeit lang in meinen Saves – und quälte mich darüber, weil etwas nicht ganz richtig zu sein schien – bis ich heute die Duplizierung erkannte (nachdem ich die andere bearbeitet hatte, um sie klarer zu machen und den Titel zu verbessern).
– Karl Knechtel
2. März um 5:41