Verwendung von sorted () und sort () in Python

Verwendung von sorted () und sort () in Python

Alle Programmierer müssen irgendwann Code schreiben, um Elemente oder Daten zu sortieren. Das Sortieren kann für die Benutzererfahrung in Ihrer Anwendung von entscheidender Bedeutung sein, unabhängig davon, ob die letzte Aktivität eines Benutzers nach Zeitstempel sortiert oder eine Liste der E-Mail-Empfänger in alphabetischer Reihenfolge nach Nachnamen angezeigt wird. Die Python-Sortierfunktion bietet robuste Funktionen zum einfachen Sortieren oder Anpassen der Bestellung auf granularer Ebene.

In diesem Handbuch erfahren Sie, wie Sie verschiedene Datentypen in verschiedenen Datenstrukturen sortieren, die Reihenfolge anpassen und in Python mit zwei verschiedenen Sortiermethoden arbeiten.

Am Ende dieses Tutorials erfahren Sie, wie Sie:

  • Implementieren Sie die grundlegende Sortierung und Reihenfolge von Python in Datenstrukturen

  • Unterscheiden Sie zwischensorted() und.sort()

  • Passen Sie eine komplexe Sortierreihenfolge in Ihrem Code basierend auf individuellen Anforderungen an

Für dieses Tutorial benötigen Sie ein grundlegendes Verständnis vonlists and tuples sowiesets. Diese Datenstrukturen werden in diesem Lernprogramm verwendet und einige grundlegende Operationen werden an ihnen ausgeführt. Außerdem verwendet dieses Lernprogramm Python 3, sodass die Beispielausgabe in diesem Lernprogramm geringfügig variieren kann, wenn Sie Python 2 verwenden.

Free Bonus:Click here to get access to a chapter from Python Tricks: The Book zeigt Ihnen die Best Practices von Python anhand einfacher Beispiele, die Sie sofort anwenden können, um schöneren + Pythonic-Code zu schreiben.

Bestellwerte mitsorted()

Um mit der Python-Sortierung zu beginnen, erfahren Sie zunächst, wie Sie sowohl numerische Daten als auch Zeichenfolgendaten sortieren.

Nummern sortieren

Sie können Python verwenden, um eine Liste mitsorted() zu sortieren. In diesem Beispiel wird eine Liste von Ganzzahlen definiert, und dann wirdsorted() mit der Variablennumbers als Argument aufgerufen:

>>>

>>> numbers = [6, 9, 3, 1]
>>> sorted(numbers)
[1, 3, 6, 9]
>>> numbers
[6, 9, 3, 1]

Die Ausgabe dieses Codes ist eine neue, sortierte Liste. Wenn die ursprüngliche Variable gedruckt wird, bleiben die Anfangswerte unverändert.

Dieses Beispiel zeigt vier wichtige Merkmale vonsorted():

  1. Die Funktionsorted() musste nicht definiert werden. Es ist eine integrierte Funktion, die in einer Standardinstallation von Python verfügbar ist.

  2. sorted() ordnet die Werte innumbers ohne zusätzliche Argumente oder Parameter in aufsteigender Reihenfolge an, dh vom kleinsten zum größten.

  3. Die ursprüngliche Variablenumbers bleibt unverändert, dasorted() eine sortierte Ausgabe liefert und den ursprünglichen Wert nicht ändert.

  4. Wennsorted() aufgerufen wird, wird eine geordnete Liste als Rückgabewert bereitgestellt.

Dieser letzte Punkt bedeutet, dasssorted() für eine Liste verwendet werden kann und die Ausgabe sofort einer Variablen zugewiesen werden kann:

>>>

>>> numbers = [6, 9, 3, 1]
>>> numbers_sorted = sorted(numbers)
>>> numbers_sorted
[1, 3, 6, 9]
>>> numbers
[6, 9, 3, 1]

In diesem Beispiel gibt es jetzt eine neue Variablenumbers_sorted, die die Ausgabe vonsorted() gespeichert hat.

Sie können alle diese Beobachtungen bestätigen, indem Siehelp() aufsorted() aufrufen. Die optionalen Argumentekey undreverse werden später im Lernprogramm behandelt:

>>>

>>> # Python 3
>>> help(sorted)
Help on built-in function sorted in module builtins:

sorted(iterable, /, *, key=None, reverse=False)
    Return a new list containing all items from the iterable in ascending order.

    A custom key function can be supplied to customize the sort order, and the
    reverse flag can be set to request the result in descending order.

Technical Detail: Wenn Sie von Python 2 wechseln und mit der gleichnamigen Funktion vertraut sind, sollten Sie einige wichtige Änderungen in Python 3 kennen:

  1. sorted() von Python 3 hat keinencmp-Parameter. Stattdessen wird nurkey verwendet, um eine benutzerdefinierte Sortierlogik einzuführen.

  2. key undreverse müssen im Gegensatz zu Python 2 als Schlüsselwortargumente übergeben werden, wo sie als Positionsargumente übergeben werden können.

Wenn Sie eine Python 2cmp-Funktion in einekey-Funktion konvertieren müssen, überprüfen Siefunctools.cmp_to_key(). Dieses Tutorial behandelt keine Beispiele mit Python 2.

sorted() kann für Tupel verwendet werden und setzt sehr ähnlich:

>>>

>>> numbers_tuple = (6, 9, 3, 1)
>>> numbers_set = {5, 5, 10, 1, 0}
>>> numbers_tuple_sorted = sorted(numbers_tuple)
>>> numbers_set_sorted = sorted(numbers_set)
>>> numbers_tuple_sorted
[1, 3, 6, 9]
>>> numbers_set_sorted
[0, 1, 5, 10]

Beachten Sie, dass die Ausgabe, obwohl die Eingabe eine Menge und ein Tupel war, eine Liste ist, dasorted() per Definition eine neue Liste zurückgibt. Das zurückgegebene Objekt kann in einen neuen Typ umgewandelt werden, wenn es mit dem Eingabetyp übereinstimmen muss. Seien Sie vorsichtig, wenn Sie versuchen, die resultierende Liste wieder in eine Menge umzuwandeln, da eine Menge per Definition ungeordnet ist:

>>>

>>> numbers_tuple = (6, 9, 3, 1)
>>> numbers_set = {5, 5, 10, 1, 0}
>>> numbers_tuple_sorted = sorted(numbers_tuple)
>>> numbers_set_sorted = sorted(numbers_set)
>>> numbers_tuple_sorted
[1, 3, 6, 9]
>>> numbers_set_sorted
[0, 1, 5, 10]
>>> tuple(numbers_tuple_sorted)
(1, 3, 6, 9)
>>> set(numbers_set_sorted)
{0, 1, 10, 5}

Der Wert vonnumbers_set_sorted bei Umwandlung inset wird nicht wie erwartet geordnet. Die andere Variable,numbers_tuple_sorted, behielt die sortierte Reihenfolge bei.

Zeichenfolgen sortieren

str Typen sortieren ähnlich wie andere iterable, wie Liste und Tupel. Das folgende Beispiel zeigt, wiesorted() jedes Zeichen in dem übergebenen Wert durchläuft und sie in der Ausgabe anordnet:

>>>

>>> string_number_value = '34521'
>>> string_value = 'I like to sort'
>>> sorted_string_number = sorted(string_number_value)
>>> sorted_string = sorted(string_value)
>>> sorted_string_number
['1', '2', '3', '4', '5']
>>> sorted_string
[' ', ' ', ' ', 'I', 'e', 'i', 'k', 'l', 'o', 'o', 'r', 's', 't', 't']

sorted() behandeltstr wie eine Liste und durchläuft jedes Element. Instr bedeutet jedes Element jedes Zeichen instr. sorted() behandelt einen Satz nicht anders und sortiert jedes Zeichen, einschließlich Leerzeichen.

.split() kann dieses Verhalten ändern und die Ausgabe bereinigen, und.join() kann alles wieder zusammensetzen. Wir werden in Kürze die spezifische Reihenfolge der Ausgabe behandeln und erklären, warum dies so ist:

>>>

>>> string_value = 'I like to sort'
>>> sorted_string = sorted(string_value.split())
>>> sorted_string
['I', 'like', 'sort', 'to']
>>> ' '.join(sorted_string)
'I like sort to'

Der ursprüngliche Satz in diesem Beispiel wird in eine Liste von Wörtern konvertiert, anstatt ihn alsstr zu belassen. Diese Liste wird dann sortiert und kombiniert, um anstelle einer Liste wieder einstr zu bilden.

Einschränkungen und Fallstricke bei der Python-Sortierung

Beachten Sie einige Einschränkungen und merkwürdige Verhaltensweisen, die auftreten können, wenn Sie Python zum Sortieren von Werten neben Ganzzahlen verwenden.

Listen mit nicht vergleichbaren Datentypen dürfen nichtsorted()ein

Es gibt Datentypen, die nicht mit nursorted() miteinander verglichen werden können, da sie zu unterschiedlich sind. Python gibt einen Fehler zurück, wenn Sie versuchen,sorted() in einer Liste mit nicht vergleichbaren Daten zu verwenden. In diesem Beispiel könnenNone undint in derselben Liste aufgrund ihrer Inkompatibilität nicht sortiert werden:

>>>

>>> mixed_types = [None, 0]
>>> sorted(mixed_types)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: '<' not supported between instances of 'int' and 'NoneType'

Dieser Fehler zeigt, warum Python die ihm zugewiesenen Werte nicht sortieren kann. Es wird versucht, die Werte zu ordnen, indem der Operator kleiner als (<) verwendet wird, um zu bestimmen, welcher Wert in der Sortierreihenfolge niedriger ist. Sie können diesen Fehler replizieren, indem Sie die beiden Werte manuell vergleichen:

>>>

>>> None < 0
Traceback (most recent call last):
  File "", line 1, in 
TypeError: '<' not supported between instances of 'NoneType' and 'int'

Das gleicheTypeError wird ausgelöst, wenn Sie versuchen, zwei nicht vergleichbare Werte zu vergleichen, ohnesorted() zu verwenden.

Wenn die Werte in der Liste verglichen werden können und keineTypeError auslösen, kann die Liste sortiert werden. Dies verhindert, dass iterable Elemente mit an sich ungeordneten Werten sortiert werden und eine Ausgabe erzeugt wird, die möglicherweise keinen Sinn ergibt.

Sollte beispielsweise die Zahl1vor dem Wortappletehen? Wenn eine Iterable jedoch eine Kombination aus Ganzzahlen und Zeichenfolgen enthält, die alle Zahlen sind, können sie mithilfe eines Listenverständnisses in vergleichbare Datentypen umgewandelt werden:

>>>

>>> mixed_numbers = [5, "1", 100, "34"]
>>> sorted(mixed_numbers)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: '<' not supported between instances of 'str' and 'int'
>>> # List comprehension to convert all values to integers
>>> [int(x) for x in mixed_numbers]
[5, 1, 100, 34]
>>> sorted([int(x) for x in mixed_numbers])
[1, 5, 34, 100]

Für jedes Element inmixed_numbers wirdint() aufgerufen, um allestr-Werte inint-Werte umzuwandeln. sorted() wird dann aufgerufen und kann jedes Element erfolgreich vergleichen und eine sortierte Ausgabe bereitstellen.

Python kann einen Wert auch implizit in einen anderen Typ konvertieren. Im folgenden Beispiel ist die Bewertung von1 <= 0 eine falsche Aussage, sodass die Ausgabe der BewertungFalse ist. Die Anzahl1 kann alsbool-Typ inTrue konvertiert werden, während0 inFalse konvertiert wird.

Obwohl die Elemente in der Liste unterschiedlich aussehen, können sie alle in Boolesche Werte (True oderFalse) konvertiert und mitsorted() miteinander verglichen werden:

>>>

>>> similar_values = [False, 0, 1, 'A' == 'B', 1 <= 0]
>>> sorted(similar_values)
[False, 0, False, False, 1]

'A' == 'B' und1 <= 0 werden inFalse konvertiert und in der geordneten Ausgabe zurückgegeben.

Dieses Beispiel zeigt einen wichtigen Aspekt der Sortierung:sort stability. Wenn Sie in Python gleiche Werte sortieren, behalten diese ihre ursprüngliche Reihenfolge in der Ausgabe bei. Obwohl sich die1verschoben haben, sind alle anderen Werte gleich, sodass sie ihre ursprüngliche Reihenfolge relativ zueinander beibehalten. Im folgenden Beispiel werden alle Werte als gleich angesehen und behalten ihre ursprüngliche Position bei:

>>>

>>> false_values = [False, 0, 0, 1 == 2, 0, False, False]
>>> sorted(false_values)
[False, 0, 0, False, 0, False, False]

Wenn Sie die ursprüngliche Reihenfolge und die sortierte Ausgabe überprüfen, werden Sie feststellen, dass1 == 2 inFalse konvertiert wird und alle sortierten Ausgaben in der ursprünglichen Reihenfolge vorliegen.

Wenn Sie Zeichenfolgen sortieren, ist der Fall wichtig

sorted() kann für eine Liste von Zeichenfolgen verwendet werden, um die Werte in aufsteigender Reihenfolge zu sortieren, die standardmäßig alphabetisch zu sein scheint:

>>>

>>> names = ['Harry', 'Suzy', 'Al', 'Mark']
>>> sorted(names)
['Al', 'Harry', 'Mark', 'Suzy']

Python verwendet jedoch dieUnicode Code Point des ersten Buchstabens in jeder Zeichenfolge, um die aufsteigende Sortierreihenfolge zu bestimmen. Das bedeutet, dasssorted() die NamenAl undal nicht gleich behandeln werden. In diesem Beispiel wirdord() verwendet, um den Unicode-Codepunkt des ersten Buchstabens in jeder Zeichenfolge zurückzugeben:

>>>

>>> names_with_case = ['harry', 'Suzy', 'al', 'Mark']
>>> sorted(names_with_case)
['Mark', 'Suzy', 'al', 'harry']
>>> # List comprehension for Unicode Code Point of first letter in each word
>>> [(ord(name[0]), name[0]) for name in sorted(names_with_case)]
[(77, 'M'), (83, 'S'), (97, 'a'), (104, 'h')]

name[0] gibt das erste Zeichen in jedem Element vonsorted(names_with_case) zurück, undord() liefert den Unicode-Codepunkt. Obwohla im Alphabet vorM steht, steht der Codepunkt fürM vora, sodass die sortierte Ausgabe zuerstM enthält.

Wenn der erste Buchstabe derselbe ist, verwendetsorted() das zweite Zeichen, um die Reihenfolge zu bestimmen, und das dritte Zeichen, wenn dies gleich ist, und so weiter bis zum Ende der Zeichenfolge:

>>>

>>> very_similar_strs = ['hhhhhd', 'hhhhha', 'hhhhhc','hhhhhb']
>>> sorted(very_similar_strs)
['hhhhha', 'hhhhhb', 'hhhhhc', 'hhhhhd']

Jeder Wert vonvery_similar_strs ist bis auf das letzte Zeichen identisch. sorted() vergleicht die Zeichenfolgen. Da die ersten fünf Zeichen identisch sind, basiert die Ausgabe auf dem sechsten Zeichen.

Zeichenfolgen mit identischen Werten werden am kürzesten bis am längsten sortiert, da die kürzeren Zeichenfolgen keine Elemente enthalten, mit denen sie mit den längeren Zeichenfolgen verglichen werden können:

>>>

>>> different_lengths = ['hhhh', 'hh', 'hhhhh','h']
>>> sorted(different_lengths)
['h', 'hh', 'hhhh', 'hhhhh']

Die kürzeste Zeichenfolgeh wird zuerst geordnet, die längstehhhhh zuletzt.

Verwenden vonsorted() Mit einemreverse-Argument

Wie in der Dokumentation zuhelp() fürsorted() gezeigt, gibt es ein optionales Schlüsselwortargument namensreverse, das das Sortierverhalten basierend auf dem ihm zugewiesenen Booleschen Wert ändert. WennreverseTrue zugewiesen ist, erfolgt die Sortierung in absteigender Reihenfolge:

>>>

>>> names = ['Harry', 'Suzy', 'Al', 'Mark']
>>> sorted(names)
['Al', 'Harry', 'Mark', 'Suzy']
>>> sorted(names, reverse=True)
['Suzy', 'Mark', 'Harry', 'Al']

Die Sortierlogik bleibt gleich, was bedeutet, dass die Namen immer noch nach ihrem Anfangsbuchstaben sortiert werden. Die Ausgabe wurde jedoch mit dem Schlüsselwortreverse aufTrue umgekehrt.

WennFalse zugewiesen ist, bleibt die Reihenfolge aufsteigend. Jedes der vorherigen Beispiele kann verwendet werden, um das Verhalten der Umkehrung unter Verwendung vonTrue oderFalse zu sehen:

>>>

>>> names_with_case = ['harry', 'Suzy', 'al', 'Mark']
>>> sorted(names_with_case, reverse=True)
['harry', 'al', 'Suzy', 'Mark']
>>> similar_values = [False, 1, 'A' == 'B', 1 <= 0]
>>> sorted(similar_values, reverse=True)
[1, False, False, False]
>>> numbers = [6, 9, 3, 1]
>>> sorted(numbers, reverse=False)
[1, 3, 6, 9]

sorted() Mit einemkey Argument

Eine der mächtigsten Komponenten vonsorted() ist das Schlüsselwortargumentkey. Dieses Argument erwartet, dass eine Funktion an sie übergeben wird, und diese Funktion wird für jeden Wert in der Liste verwendet, der sortiert wird, um die resultierende Reihenfolge zu bestimmen.

Nehmen wir zur Veranschaulichung eines grundlegenden Beispiels an, dass für die Bestellung einer bestimmten Liste die Länge der Zeichenfolgen in der Liste vom kürzesten zum längsten erforderlich ist. Die Funktion zum Zurückgeben der Länge eines Strings,len(), wird mit dem Argumentkey verwendet:

>>>

>>> word = 'paper'
>>> len(word)
5
>>> words = ['banana', 'pie', 'Washington', 'book']
>>> sorted(words, key=len)
['pie', 'book', 'banana', 'Washington']

Die resultierende Reihenfolge ist eine Liste mit einer Zeichenfolgenreihenfolge von kürzester bis längster. Die Länge jedes Elements in der Liste wird durchlen() bestimmt und dann in aufsteigender Reihenfolge zurückgegeben.

Kehren wir zum früheren Beispiel der Sortierung nach Anfangsbuchstaben zurück, wenn der Fall anders ist. key kann verwendet werden, um dieses Problem zu lösen, indem die gesamte Zeichenfolge in Kleinbuchstaben konvertiert wird:

>>>

>>> names_with_case = ['harry', 'Suzy', 'al', 'Mark']
>>> sorted(names_with_case)
['Mark', 'Suzy', 'al', 'harry']
>>> sorted(names_with_case, key=str.lower)
['al', 'harry', 'Mark', 'Suzy']

Die Ausgabewerte wurden nicht in Kleinbuchstaben konvertiert, dakey die Daten in der ursprünglichen Liste nicht manipuliert. Während des Sortierens wird die ankey übergebene Funktion für jedes Element aufgerufen, um die Sortierreihenfolge zu bestimmen. Die ursprünglichen Werte werden jedoch in der Ausgabe angezeigt.

Es gibt zwei Haupteinschränkungen, wenn Sie Funktionen mit dem Argumentkeyverwenden.

Erstens muss die Anzahl der erforderlichen Argumente in der ankey übergebenen Funktion eins sein.

Das folgende Beispiel zeigt die Definition einer Additionsfunktion, die zwei Argumente akzeptiert. Wenn diese Funktion inkey in einer Liste von Zahlen verwendet wird, schlägt sie fehl, weil ein zweites Argument fehlt. Jedes Mal, wennadd() während der Sortierung aufgerufen wird, empfängt es jeweils nur ein Element aus der Liste:

>>>

>>> def add(x, y):
...     return x + y
...
>>> values_to_add = [1, 2, 3]
>>> sorted(values_to_add, key=add)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: add() missing 1 required positional argument: 'y'

Die zweite Einschränkung besteht darin, dass die mitkey verwendete Funktion alle Werte in der Iterable verarbeiten kann. Beispielsweise haben Sie eine Liste von Zahlen, die als Zeichenfolgen dargestellt werden, die insorted() verwendet werden sollen, undkey wird versuchen, sie mitint in Zahlen umzuwandeln. Wenn ein Wert in der Iterable nicht in eine Ganzzahl umgewandelt werden kann, schlägt die Funktion fehl:

>>>

>>> values_to_cast = ['1', '2', '3', 'four']
>>> sorted(values_to_cast, key=int)
Traceback (most recent call last):
  File "", line 1, in 
ValueError: invalid literal for int() with base 10: 'four'

Jeder numerische Wert alsstr kann inint konvertiert werden,four jedoch nicht. Dies führt dazu, dass einValueError ausgelöst wird und erklärt wird, dassfour nicht inint konvertiert werden kann, da es ungültig ist.

Die Funktionalität vonkeyist äußerst leistungsfähig, da fast jede integrierte oder benutzerdefinierte Funktion zum Bearbeiten der Ausgabereihenfolge verwendet werden kann.

Wenn die Bestellanforderung darin besteht, eine Iterierbarkeit nach dem letzten Buchstaben in jeder Zeichenfolge zu bestellen (und wenn der Buchstabe derselbe ist, dann den nächsten Buchstaben zu verwenden), kann einfunction definiert und dann bei der Sortierung verwendet werden. Das folgende Beispiel definiert eine Funktion, die die an sie übergebene Zeichenfolge umkehrt, und diese Funktion wird dann als Argument fürkey verwendet:

>>>

>>> def reverse_word(word):
...     return word[::-1]
...
>>> words = ['banana', 'pie', 'Washington', 'book']
>>> sorted(words, key=reverse_word)
['banana', 'pie', 'book', 'Washington']

Die Slice-Syntax vonword[::-1]wird verwendet, um eine Zeichenfolge umzukehren. Auf jedes Element wirdreverse_word() angewendet, und die Sortierreihenfolge basiert auf den Zeichen im Rückwärtswort.

Anstatt eine eigenständige Funktion zu schreiben, können Sie einelambda-Funktion verwenden, die im Argumentkeydefiniert ist.

Alambda ist eine anonyme Funktion, die:

  1. Muss inline definiert werden

  2. Hat keinen Namen

  3. Kann keinestatements enthalten

  4. Wird wie eine Funktion ausgeführt

Im folgenden Beispiel istkey alslambda ohne Namen definiert, das Argument vonlambda istx undx[::-1] ist die Operation das wird mit dem Argument durchgeführt:

>>>

>>> words = ['banana', 'pie', 'Washington', 'book']
>>> sorted(words, key=lambda x: x[::-1])
['banana', 'pie', 'book', 'Washington']

x[::-1] wird für jedes Element aufgerufen und kehrt das Wort um. Diese umgekehrte Ausgabe wird dann zum Sortieren verwendet, aber die ursprünglichen Wörter werden immer noch zurückgegeben.

Wenn sich die Anforderung ändert und die Reihenfolge ebenfalls umgekehrt werden sollte, kann das Schlüsselwortreverseneben dem Argumentkeyverwendet werden:

>>>

>>> words = ['banana', 'pie', 'Washington', 'book']
>>> sorted(words, key=lambda x: x[::-1], reverse=True)
['Washington', 'book', 'pie', 'banana']

Die Funktionen vonlambdaind auch nützlich, wenn Sieclass Objekte basierend auf einer Eigenschaft sortieren müssen. Wenn Sie eine Gruppe von Schülern haben und diese nach ihrer höchsten bis niedrigsten Abschlussnote sortieren müssen, können Sie mitlambda die Eigenschaftgrade ausclass abrufen:

>>>

>>> from collections import namedtuple

>>> StudentFinal = namedtuple('StudentFinal', 'name grade')
>>> bill = StudentFinal('Bill', 90)
>>> patty = StudentFinal('Patty', 94)
>>> bart = StudentFinal('Bart', 89)
>>> students = [bill, patty, bart]
>>> sorted(students, key=lambda x: getattr(x, 'grade'), reverse=True)
[StudentFinal(name='Patty', grade=94), StudentFinal(name='Bill', grade=90), StudentFinal(name='Bart', grade=89)]

In diesem Beispiel werdennamedtuple verwendet, um Klassen mit den Attributenname undgrade zu erstellen. lambda ruft für jedes Elementgetattr() auf und gibt den Wert fürgrade zurück.

reverse wird aufTrue gesetzt, damit die aufsteigende Ausgabe absteigend gespiegelt wird, sodass die höchsten Noten zuerst geordnet werden.

Es gibt unendlich viele Möglichkeiten, wie Sie bestellen können, wenn Sie die Schlüsselwortargumentekey undreversefürsorted() verwenden. Code kann sauber und kurz gehalten werden, wenn Sie ein einfacheslambda für eine kleine Funktion verwenden, oder Sie können eine ganz neue Funktion schreiben, importieren und im Schlüsselargument verwenden.

Bestellwerte mit.sort()

Das sehr ähnlich benannte.sort() unterscheidet sich erheblich von dem eingebautensorted(). Sie erreichen mehr oder weniger dasselbe, aber diehelp()-Dokumentation fürlist.sort() zeigt zwei der kritischsten Unterschiede zwischen.sort() undsorted() auf:

>>>

>>> # Python2
Help on method_descriptor:

sort(...)
    L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;
    cmp(x, y) -> -1, 0, 1

>>> # Python3
>>> help(list.sort)
Help on method_descriptor:

sort(...)
    L.sort(key=None, reverse=False) -> None -- stable sort *IN PLACE*

Erstens ist sort eine Methode der Klasselistund kann nur mit Listen verwendet werden. Es ist kein eingebautes Element, an das eine Iteration übergeben wird.

Zweitens gibt.sort()None zurück und ändert die vorhandenen Werte. Werfen wir einen Blick auf die Auswirkungen dieser beiden Unterschiede im Code:

>>>

>>> values_to_sort = [5, 2, 6, 1]
>>> # Try to call .sort() like sorted()
>>> sort(values_to_sort)
Traceback (most recent call last):
  File "", line 1, in 
NameError: name 'sort' is not defined

>>> # Try to use .sort() on a tuple
>>> tuple_val = (5, 1, 3, 5)
>>> tuple_val.sort()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'tuple' object has no attribute 'sort'

>>> # Sort the list and assign to new variable
>>> sorted_values = values_to_sort.sort()
>>> print(sorted_values)
None

>>> # Print original variable
>>> print(values_to_sort)
[1, 2, 5, 6]

In diesem Codebeispiel gibt es einige ziemlich dramatische Unterschiede in der Funktionsweise von.sort() im Vergleich zusorted():

  1. Es gibt keine geordnete Ausgabe von.sort(), daher übergibt die Zuordnung zu einer neuen Variablen nur den TypNone.

  2. Dievalues_to_sort-Liste wurde geändert, und die ursprüngliche Reihenfolge wird in keiner Weise beibehalten.

Diese Verhaltensunterschiede machen.sort() undsorted() im Code absolut nicht austauschbar und können zu völlig unerwarteten Ergebnissen führen, wenn man sie falsch verwendet.

.sort() hat dieselben optionalen Schlüsselwortargumentekey undreverse, die dieselbe robuste Funktionalität wiesorted() erzeugen. Hier können Sie eine Liste von Phrasen nach dem zweiten Buchstaben des dritten Wortes sortieren und die Liste in umgekehrter Reihenfolge zurückgeben:

>>>

>>> phrases = ['when in rome',
...     'what goes around comes around',
...     'all is fair in love and war'
...     ]
>>> phrases.sort(key=lambda x: x.split()[2][1], reverse=True)
>>> phrases
['what goes around comes around', 'when in rome', 'all is fair in love and war']

In diesem Beispiel wird einlambda verwendet, um Folgendes zu tun:

  1. Teilen Sie jede Phrase in eine Liste von Wörtern

  2. Suchen Sie das dritte Element oder Wort in diesem Fall

  3. Finden Sie den zweiten Buchstaben in diesem Wort

Wann werdensorted() und wann.sort() verwendet?

Sie haben die Unterschiede zwischensorted() und.sort() gesehen, aber wann verwenden Sie welche?

Nehmen wir an, es steht ein 5-km-Rennen an: Das erste jährliche Python-5-km-Rennen. Die Daten aus dem Rennen müssen erfasst und sortiert werden. Die Daten, die erfasst werden müssen, sind die Startnummer des Läufers und die Anzahl der Sekunden, die zum Beenden des Rennens benötigt wurden:

>>>

>>> from collections import namedtuple

>>> Runner = namedtuple('Runner', 'bibnumber duration')

Wenn die Läufer die Ziellinie überqueren, wird jedesRunner zu einer Liste mit dem Namenrunners hinzugefügt. Bei 5-km-Rennen überqueren nicht alle Läufer gleichzeitig die Startlinie, sodass die erste Person, die die Ziellinie überquert, möglicherweise nicht die schnellste Person ist:

>>>

>>> runners = []
>>> runners.append(Runner('2528567', 1500))
>>> runners.append(Runner('7575234', 1420))
>>> runners.append(Runner('2666234', 1600))
>>> runners.append(Runner('2425234', 1490))
>>> runners.append(Runner('1235234', 1620))
>>> # Thousands and Thousands of entries later...
>>> runners.append(Runner('2526674', 1906))

Jedes Mal, wenn ein Läufer die Ziellinie überquert, werden seine Startnummer und seine Gesamtdauer in Sekunden zurunners addiert.

Jetzt sieht der pflichtbewusste Programmierer, der für die Verarbeitung der Ergebnisdaten verantwortlich ist, diese Liste, weiß, dass die fünf schnellsten Teilnehmer die Gewinner sind, die Preise erhalten, und die verbleibenden Läufer werden nach der schnellsten Zeit sortiert.

Es gibt keine Anforderungen für mehrere Arten der Sortierung nach verschiedenen Attributen. Die Liste hat eine angemessene Größe. Es wird nicht erwähnt, dass die Liste irgendwo gespeichert wird. Sortieren Sie einfach nach Dauer und holen Sie sich die fünf Teilnehmer mit der niedrigsten Dauer:

>>>

>>> runners.sort(key=lambda x: getattr(x, 'duration'))
>>> top_five_runners = runners[:5]

Der Programmierer verwendetlambda im Argumentkey, um das Attributduration von jedem Läufer abzurufen undrunners mit.sort() zu sortieren. Nachdemrunners sortiert wurde, werden die ersten 5 Elemente intop_five_runners gespeichert.

Mission erfüllt! Der Rennleiter kommt vorbei und informiert den Programmierer, dass er seit der aktuellen Version von Python 3.7 entschieden hat, dass jede siebenunddreißigste Person, die die Ziellinie überquert hat, eine kostenlose Sporttasche bekommt.

Zu diesem Zeitpunkt beginnt der Programmierer zu schwitzen, da die Liste der Läufer irreversibel geändert wurde. Es gibt keine Möglichkeit, die ursprüngliche Liste der Läufer in der Reihenfolge wiederherzustellen, in der sie fertig sind, und jede siebenunddreißigste Person zu finden.

Wenn Sie mit wichtigen Daten arbeiten und sogar die Möglichkeit besteht, dass die Originaldaten wiederhergestellt werden müssen, ist.sort() nicht die beste Option. Wenn es sich bei den Daten um eine Kopie handelt, wenn es sich um unwichtige Arbeitsdaten handelt oder wenn es niemandem etwas ausmacht, sie zu verlieren, weil sie abgerufen werden können, kann.sort() eine gute Option sein.

Alternativ könnten die Läufer mitsorted() und mit denselbenlambda sortiert worden sein:

>>>

>>> runners_by_duration = sorted(runners, key=lambda x: getattr(x, 'duration'))
>>> top_five_runners = runners_by_duration[:5]

In diesem Szenario mitsorted() ist die ursprüngliche Liste der Läufer noch intakt und wurde nicht überschrieben. Die spontane Anforderung, jede siebenunddreißigste Person zum Überqueren der Ziellinie zu finden, kann durch Interaktion mit den ursprünglichen Werten erreicht werden:

>>>

>>> every_thirtyseventh_runners = runners[::37]

every_thirtyseventh_runners wird mithilfe eines Schrittes in der Listen-Slice-Syntax fürrunners erstellt, der noch die ursprüngliche Reihenfolge enthält, in der die Läufer die Ziellinie überquert haben.

So sortieren Sie in Python: Fazit

.sort() undsorted() können genau die Sortierreihenfolge bereitstellen, die Sie benötigen, wenn Sie sie ordnungsgemäß mit den optionalen Schlüsselwortargumentenreverse undkeyverwenden.

Beide haben sehr unterschiedliche Eigenschaften in Bezug auf Ausgabe und direkte Änderungen. Denken Sie also über alle Anwendungsfunktionen oder -programme nach, die.sort() verwenden, da sie Daten unwiderruflich überschreiben können.

Versuchen Sie für begeisterte Pythonisten, die eine Herausforderung beim Sortieren suchen, komplexere Datentypen beim Sortieren zu verwenden: verschachtelte iterable. Sie können auch in die Open-Source-Python-Code-Implementierungen für die integrierten Funktionen eintauchen und sich über den in Python verwendeten Sortieralgorithmus namensTimsort informieren.