Wie sortiere ich eine Liste / ein Tupel von Listen / Tupeln nach dem Element an einem bestimmten Index?


657

Ich habe einige Daten entweder in einer Liste von Listen oder einer Liste von Tupeln, wie folgt:

data = [[1,2,3], [4,5,6], [7,8,9]]
data = [(1,2,3), (4,5,6), (7,8,9)]

Und ich möchte nach dem 2. Element in der Teilmenge sortieren. Das heißt, Sortieren nach 2,5,8, woher 2kommt (1,2,3), 5kommt von (4,5,6). Was ist der übliche Weg, dies zu tun? Soll ich Tupel oder Listen in meiner Liste speichern?


51
In Bezug auf "Soll ich Tupel oder Listen in meiner Liste speichern?" Lautet die Faustregel, die Dinge so unveränderlich wie möglich zu machen. Wenn Sie die vorhandenen Unterlisten nicht ändern müssen , erstellen Sie sie zu Tupeln.
Matthew Flaschen

Antworten:


1112
sorted_by_second = sorted(data, key=lambda tup: tup[1])

oder:

data.sort(key=lambda tup: tup[1])  # sorts in place

10
Irgendeine Idee, wie man es größer zu kleiner sortiert?
Billwild

63
@billwild: Hilfe (sortiert). reverse = True.
Stephen

34
@ Stephen mit itemgetter ist schneller und einfacher: key=itemgetter(1)und am Anfang der Datei:from operator import itemgetter
Joschua

3
@Cemre wie im zweiten Beispiel ist sorthier eine ListObjektmethode von Python, die eine Lambda-Funktion als keyParameter erhält . Sie können es als tupoder oder toder was auch immer Sie mögen benennen und es wird immer noch funktionieren. tupHier wird der Index des Tupels der Liste angegeben. Dies 1bedeutet, dass die Sortierung nach den zweiten Werten der Tupel aus der ursprünglichen Liste ( 2, 5, 8) durchgeführt wird.
Neurotransmitter

1
Ich war leicht skeptisch gegenüber der unbegründeten Behauptung, dass "die Verwendung von Itemgetter schneller und einfacher ist". Während ich den intuitiven lambdaAnsatz subjektiv als einfacher als die unintuitive itemgetterKlasse betrachte, itemgetter scheint er tatsächlich schneller zu sein . Ich bin gespannt, warum das so ist. Mein grober Verdacht ist, dass a lambdadie versteckten Kosten für die Erfassung aller lokalen Variablen in einem Abschlusskontext verursacht, während dies bei einer itemgetterInstanz nicht der Fall ist. tl; dr: Immer verwenden itemgetter, weil die Geschwindigkeit gewinnt.
Cecil Curry

235
from operator import itemgetter
data.sort(key=itemgetter(1))

37
Dies sollte die akzeptierte Antwort sein. Siehe auch Charlie ‚s geschrieben Timings , die demonstrieren itemgetterKlasse zu sortieren 126% schneller als im Durchschnitt der äquivalente lambdaFunktion.
Cecil Curry

9
Sie können auch hierarchisch nach mehreren Indizes sortieren, z. B.data.sort(key=itemgetter(3,1))
Michael Ohlrogge

57

Ich möchte nur zu Stephens Antwort hinzufügen, wenn Sie das Array von hoch nach niedrig sortieren möchten. Eine andere Möglichkeit als in den obigen Kommentaren besteht darin, dies der Zeile hinzuzufügen:

reverse = True

und das Ergebnis wird wie folgt sein:

data.sort(key=lambda tup: tup[1], reverse=True)

48

Zum Sortieren nach mehreren Kriterien, nämlich zum Beispiel nach dem zweiten und dritten Element in einem Tupel, sei

data = [(1,2,3),(1,2,1),(1,1,4)]

Definieren Sie daher ein Lambda, das beispielsweise ein Tupel zurückgibt, das die Priorität beschreibt

sorted(data, key=lambda tup: (tup[1],tup[2]) )
[(1, 1, 4), (1, 2, 1), (1, 2, 3)]

28

Stephens Antwort ist die, die ich verwenden würde. Der Vollständigkeit halber hier das DSU-Muster (Decorate-Sort-Undecorate) mit Listenverständnis:

decorated = [(tup[1], tup) for tup in data]
decorated.sort()
undecorated = [tup for second, tup in decorated]

Oder knapper:

[b for a,b in sorted((tup[1], tup) for tup in data)]

Wie im Python Sorting HowTo erwähnt , war dies seit Python 2.4, als Schlüsselfunktionen verfügbar wurden, nicht mehr erforderlich .


2
Diese Antwort ist also nützlich für Python 2.3-? Gibt es in aktuelleren Python-Versionen gültige Verwendungszwecke, auf die Sie möglicherweise näher eingehen? Wenn nicht, keine Mühe ... kam gerade vorbei, sah dies und der alte Noggin musste nur ein kleines bisschen herumwirbeln. Wie auch immer, Prost und danke für diesen Spaziergang zurück in die früheren Tage von Python.
mechanisches

19

Um eine Liste von Tupeln zu sortieren (<word>, <count>), für countin absteigender Reihenfolge und wordin alphabetischer Reihenfolge:

data = [
('betty', 1),
('bought', 1),
('a', 1),
('bit', 1),
('of', 1),
('butter', 2),
('but', 1),
('the', 1),
('was', 1),
('bitter', 1)]

Ich benutze diese Methode:

sorted(data, key=lambda tup:(-tup[1], tup[0]))

und es gibt mir das Ergebnis:

[('butter', 2),
('a', 1),
('betty', 1),
('bit', 1),
('bitter', 1),
('bought', 1),
('but', 1),
('of', 1),
('the', 1),
('was', 1)]

1
Was ist, wenn tup [1] eine Zeichenfolge ist?
Eric

12

Ohne Lambda:

def sec_elem(s):
    return s[1]

sorted(data, key=sec_elem)

9

itemgetter()ist etwas schneller als lambda tup: tup[1], aber der Anstieg ist relativ gering (etwa 10 bis 25 Prozent).

(IPython-Sitzung)

>>> from operator import itemgetter
>>> from numpy.random import randint
>>> values = randint(0, 9, 30000).reshape((10000,3))
>>> tpls = [tuple(values[i,:]) for i in range(len(values))]

>>> tpls[:5]    # display sample from list
[(1, 0, 0), 
 (8, 5, 5), 
 (5, 4, 0), 
 (5, 7, 7), 
 (4, 2, 1)]

>>> sorted(tpls[:5], key=itemgetter(1))    # example sort
[(1, 0, 0), 
 (4, 2, 1), 
 (5, 4, 0), 
 (8, 5, 5), 
 (5, 7, 7)]

>>> %timeit sorted(tpls, key=itemgetter(1))
100 loops, best of 3: 4.89 ms per loop

>>> %timeit sorted(tpls, key=lambda tup: tup[1])
100 loops, best of 3: 6.39 ms per loop

>>> %timeit sorted(tpls, key=(itemgetter(1,0)))
100 loops, best of 3: 16.1 ms per loop

>>> %timeit sorted(tpls, key=lambda tup: (tup[1], tup[0]))
100 loops, best of 3: 17.1 ms per loop

In der Itemgetter-Sortierlösung finden Sie Informationen zum Variieren von umgekehrten Argumenten für mehrere Spalten. Anschließend müssen Sie Ihre Sortierung in mehreren Schritten hintereinander anordnen
Lorenz,

6

@ Stephens Antwort ist auf den Punkt! Hier ist ein Beispiel für eine bessere Visualisierung:

Grüße die Fans von Ready Player One! =)

>>> gunters = [('2044-04-05', 'parzival'), ('2044-04-07', 'aech'), ('2044-04-06', 'art3mis')]
>>> gunters.sort(key=lambda tup: tup[0])
>>> print gunters
[('2044-04-05', 'parzival'), ('2044-04-06', 'art3mis'), ('2044-04-07', 'aech')]

keyist eine Funktion, die aufgerufen wird, um die Elemente der Sammlung zum Vergleich zu transformieren. like compareToMethode in Java.

Der an key übergebene Parameter muss aufrufbar sein. Hier lambdaerzeugt die Verwendung von eine anonyme Funktion (die aufrufbar ist).
Die Syntax von Lambda ist das Wort Lambda, gefolgt von einem iterierbaren Namen und einem einzelnen Codeblock.

Im folgenden Beispiel sortieren wir eine Liste von Tupeln, die die Informationen zum Zeitpunkt eines bestimmten Ereignisses und des Darstellernamens enthalten.

Wir sortieren diese Liste nach dem Zeitpunkt des Auftretens des Ereignisses - dem 0. Element eines Tupels.

Hinweis - s.sort([cmp[, key[, reverse]]]) sortiert die Elemente von s an Ort und Stelle


-5

Das Sortieren eines Tupels ist ganz einfach:

tuple(sorted(t))
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.