Python hat eine stabile Sortierung. Sofern die Leistung kein Problem darstellt, ist es am einfachsten, sie nach Feld 2 zu sortieren und dann erneut nach Feld 1 zu sortieren.
Das gibt Ihnen das gewünschte Ergebnis. Der einzige Haken ist, dass das zweimalige Aufrufen von sort einen inakzeptablen Aufwand bedeuten kann, wenn es sich um eine große Liste handelt (oder wenn Sie sie häufig sortieren möchten).
list1 = sorted(csv1, key=operator.itemgetter(2))
list1 = sorted(list1, key=operator.itemgetter(1))
Auf diese Weise können Sie auch problemlos die Situation bewältigen, in der einige Spalten umgekehrt sortiert werden sollen. Fügen Sie bei Bedarf einfach den Parameter 'reverse = True' hinzu.
Andernfalls können Sie mehrere Parameter an itemgetter übergeben oder manuell ein Tupel erstellen. Das wird wahrscheinlich schneller sein, hat aber das Problem, dass es nicht gut verallgemeinert wird, wenn einige der Spalten umgekehrt sortiert werden sollen (numerische Spalten können immer noch umgekehrt werden, indem sie negiert werden, aber das verhindert, dass die Sortierung stabil ist).
Wenn Sie also keine Spalten in umgekehrter Reihenfolge benötigen, wählen Sie Itemgetter, wenn Sie möchten, mehrere Argumente, und die Spalten sind nicht numerisch, oder Sie möchten die Sortierung für mehrere aufeinanderfolgende Sortierungen stabil halten.
Bearbeiten: Für die Kommentatoren, die Probleme haben zu verstehen, wie dies die ursprüngliche Frage beantwortet, ist hier ein Beispiel, das genau zeigt, wie die stabile Art der Sortierung sicherstellt, dass wir für jeden Schlüssel separate Sortierungen durchführen und am Ende Daten nach mehreren Kriterien sortieren können:
DATA = [
('Jones', 'Jane', 58),
('Smith', 'Anne', 30),
('Jones', 'Fred', 30),
('Smith', 'John', 60),
('Smith', 'Fred', 30),
('Jones', 'Anne', 30),
('Smith', 'Jane', 58),
('Smith', 'Twin2', 3),
('Jones', 'John', 60),
('Smith', 'Twin1', 3),
('Jones', 'Twin1', 3),
('Jones', 'Twin2', 3)
]
# Sort by Surname, Age DESCENDING, Firstname
print("Initial data in random order")
for d in DATA:
print("{:10s} {:10s} {}".format(*d))
print('''
First we sort by first name, after this pass all
Twin1 come before Twin2 and Anne comes before Fred''')
DATA.sort(key=lambda row: row[1])
for d in DATA:
print("{:10s} {:10s} {}".format(*d))
print('''
Second pass: sort by age in descending order.
Note that after this pass rows are sorted by age but
Twin1/Twin2 and Anne/Fred pairs are still in correct
firstname order.''')
DATA.sort(key=lambda row: row[2], reverse=True)
for d in DATA:
print("{:10s} {:10s} {}".format(*d))
print('''
Final pass sorts the Jones from the Smiths.
Within each family members are sorted by age but equal
age members are sorted by first name.
''')
DATA.sort(key=lambda row: row[0])
for d in DATA:
print("{:10s} {:10s} {}".format(*d))
Dies ist ein ausführbares Beispiel, aber um die Benutzer zu retten, die es ausführen, lautet die Ausgabe wie folgt:
Initial data in random order
Jones Jane 58
Smith Anne 30
Jones Fred 30
Smith John 60
Smith Fred 30
Jones Anne 30
Smith Jane 58
Smith Twin2 3
Jones John 60
Smith Twin1 3
Jones Twin1 3
Jones Twin2 3
First we sort by first name, after this pass all
Twin1 come before Twin2 and Anne comes before Fred
Smith Anne 30
Jones Anne 30
Jones Fred 30
Smith Fred 30
Jones Jane 58
Smith Jane 58
Smith John 60
Jones John 60
Smith Twin1 3
Jones Twin1 3
Smith Twin2 3
Jones Twin2 3
Second pass: sort by age in descending order.
Note that after this pass rows are sorted by age but
Twin1/Twin2 and Anne/Fred pairs are still in correct
firstname order.
Smith John 60
Jones John 60
Jones Jane 58
Smith Jane 58
Smith Anne 30
Jones Anne 30
Jones Fred 30
Smith Fred 30
Smith Twin1 3
Jones Twin1 3
Smith Twin2 3
Jones Twin2 3
Final pass sorts the Jones from the Smiths.
Within each family members are sorted by age but equal
age members are sorted by first name.
Jones John 60
Jones Jane 58
Jones Anne 30
Jones Fred 30
Jones Twin1 3
Jones Twin2 3
Smith John 60
Smith Jane 58
Smith Anne 30
Smith Fred 30
Smith Twin1 3
Smith Twin2 3
Beachten Sie insbesondere, wie im zweiten Schritt der reverse=True
Parameter die Vornamen in der richtigen Reihenfolge hält, während durch einfaches Sortieren und Umkehren der Liste die gewünschte Reihenfolge für den dritten Sortierschlüssel verloren geht.