Python sortiert

Fr, 3. Dezember 2021, Ralf Hersel

Beginnen wir diesen Freitag mit ein paar Python-Fingerübungen. Die Bearbeitung von Listen gehört zu den beliebten und starken Funktionen dieser Programmiersprache. Ab und zu hat man die Anforderung, eine Liste zu sortieren. Das ist kein Problem in Python; etwas schwieriger wird es, wenn es sich dabei um mehrdimensionale Listen handelt.

Los geht es mit einer einfachen Liste:

person = ['Dieter','Anna','Fritz','Beate','Emilie','Caesar']
person.sort()
person
['Anna', 'Beate', 'Caesar', 'Dieter', 'Emilie', 'Fritz']

Das funktioniert auch in umgekehrter Richtung:

person.sort(reverse=True)
person
['Fritz', 'Emilie', 'Dieter', 'Caesar', 'Beate', 'Anna']

Wie man sieht, führt die Sort-Methode eine in-place Modifikation durch; die Originalliste wird sortiert. Aber wie funktioniert die Sortierung, wenn die Liste mehrere Dimensionen hat?

Zuerst einmal erstellen wir eine solche Liste, indem Alter und Geschlecht hinzugefügt wird:

person = [
['Dieter',34,'m'],
['Anna',18,'w'],
['Fritz',25,'w'],
['Beate',43,'w'],
['Emilie',10,'w'],
['Caesar',54,'m']]
person.sort()
person
[['Anna', 18, 'w'],
['Beate', 43, 'w'],
['Caesar', 54, 'm'],
['Dieter', 34, 'm'],
['Emilie', 10, 'w'],
['Fritz', 25, 'w']]

Wie man sieht, funktioniert die Sortierung auch bei mehrdimensionalen Listen, jedoch nur nach dem ersten Element (Name) jeder Unterliste. Aber was ist, wenn man nach dem Alter oder dem Geschlecht sortieren möchte. Die Methode list.sort() bietet diese Funktionalität nicht. Stattdessen kann man die Funktion sorted() einsetzen. Hier ist ein Beispiel unter Verwendung der Personenliste von oben:

sorted_person = sorted(person, key=lambda alter: alter[1])
sorted_person
[['Emilie', 10, 'w'],
['Anna', 18, 'w'],
['Fritz', 25, 'w'],
['Dieter', 34, 'm'],
['Beate', 43, 'w'],
['Caesar', 54, 'm']]

Nun ist die Liste nach dem Alter sortiert. Was man auch erkennt ist, dass die Funktion sorted() keine in-place Modifikation durchführt, sondern die Originalliste unverändert lässt. Das sortierte Ergebnis steht in der neuen Liste sorted_person. Ausserdem erschliesst sich einem die Funktionsweise nicht direkt.

Die Funktion sorted() nimmt mehrere Parameter entgegen: die Liste, eine Funktion und noch weitere. Der Parameter key erwartet eine Funktion, die das zu sortierende Element zurückliefern muss. Schaut euch dieses Beispiel an:

def f(x):
    print(x)
    return x

person = [['Dieter',34,'m'],['Anna',18,'w'],['Fritz',25,'w'],['Beate',43,'w'],['Emilie',10,'w'],['Caesar',54,'m']]
sorted_person = sorted(person, key=f)
print(sorted_person)

Die Funktion sorted() ruft die Funktion f auf und übergibt Record für Record aus der Liste. Die Funktion f macht nichts, ausser x auszugeben und x zurückzugeben. x enthält ['Dieter',34,'m'] usw. Somit erhält man dasselbe Sortierergebnis, als hätte man die Methode list.sort() angewendet. Das Ergebnis des Codes von oben sieht so aus:

ralf@ralf-laptop:~/dev$ ./sorted.py 
['Dieter', 34, 'm']
['Anna', 18, 'w']
['Fritz', 25, 'w']
['Beate', 43, 'w']
['Emilie', 10, 'w']
['Caesar', 54, 'm']
[['Anna', 18, 'w'], ['Beate', 43, 'w'], ['Caesar', 54, 'm'], ['Dieter', 34, 'm'], ['Emilie', 10, 'w'], ['Fritz', 25, 'w']]

Nun modifizieren wir die Funktion derart, dass nur das Alter zurückgegeben wird:

def f(x):
    return x[1]

[['Emilie', 10, 'w'], ['Anna', 18, 'w'], ['Fritz', 25, 'w'], ['Dieter', 34, 'm'], ['Beate', 43, 'w'], ['Caesar', 54, 'm']]

Voilà, nun versteht man, wie die Sache läuft. F(x) liefert das Alter zurück, nach dem dann sortiert wird. Aber was hat es jetzt mit dem seltsamen lambda auf sich?

sorted_person = sorted(person, key=lambda alter: alter[1])

Statt eine Funktion aufzurufen, kann man mit dem Befehl lambda die Funktion direkt als Parameter angeben. Im Beispiel wird eine namenlose Funktion aufgerufen, der das Argument alter übergeben wird und die Anweisung alter[1] enthält. Wir wissen, dass alter einen Record enthält, z.B. ['Dieter',34,'m'] und alter[1] zurückgibt, also 34. Die Funktion sorted() sorgt dafür, dass die lambda-Funktion alle Records nacheinander geliefert bekommt.

Alles klar? Falls nicht, fragt mich.

Quellen:

https://www.w3schools.com/python/ref_list_sort.asp
https://www.w3schools.com/python/ref_func_sorted.asp
https://www.w3schools.com/python/python_lambda.asp