Es gibt keine eingebaute reverse
Funktion für Pythons str
Objekt. Was ist der beste Weg, um diese Methode zu implementieren?
Wenn Sie eine sehr präzise Antwort geben, erläutern Sie bitte deren Effizienz. Zum Beispiel, ob das str
Objekt in ein anderes Objekt konvertiert wird usw.
Antworten:
Wie wäre es mit:
Dies ist eine erweiterte Slice- Syntax. Es funktioniert so: Wenn Sie
[begin:end:step]
Anfang und Ende verlassen und einen Schritt von -1 angeben, wird eine Zeichenfolge umgekehrt.quelle
b = a.decode('utf8')[::-1].encode('utf8')
aber danke für die richtige Richtung!.decode('utf8')
erforderlich, bedeuteta
dies, dass keine Zeichenfolgenobjekte, sondern Bytes enthalten sind.@ Paolo
s[::-1]
ist am schnellsten; Ein langsamerer Ansatz (vielleicht besser lesbar, aber das ist umstritten) ist''.join(reversed(s))
.quelle
join
hat die Liste zu erstellen ohnehin um die Größe erhalten zu können.''.join(list(reversed(s)))
kann etwas schneller sein.Meine eigene Erfahrung mit dieser Frage ist akademisch. Wenn Sie jedoch ein Profi sind, der nach einer schnellen Antwort sucht, verwenden Sie ein Slice, das folgende Schritte umfasst
-1
:oder besser lesbar (aber langsamer aufgrund der Suche nach Methodennamen und der Tatsache, dass Join eine Liste bildet, wenn ein Iterator angegeben wird) ,
str.join
:oder setzen Sie das Slice zur besseren Lesbarkeit und Wiederverwendbarkeit in eine Funktion ein
und dann:
Längere Erklärung
Wenn Sie an der akademischen Ausstellung interessiert sind, lesen Sie bitte weiter.
Hier sind einige Dinge über Pythons Zeichenfolgen, die Sie wissen sollten:
In Python sind Zeichenfolgen unveränderlich . Durch Ändern einer Zeichenfolge wird die Zeichenfolge nicht geändert. Es schafft eine neue.
Saiten sind in Scheiben geschnitten. Wenn Sie eine Zeichenfolge in Scheiben schneiden, erhalten Sie eine neue Zeichenfolge von einem Punkt in der Zeichenfolge vorwärts oder rückwärts zu einem anderen Punkt in bestimmten Schritten. Sie nehmen die Slice-Notation oder ein Slice-Objekt in einem Index an:
Der Index erstellt ein Slice, indem ein Doppelpunkt in die geschweiften Klammern eingefügt wird:
Um ein Slice außerhalb der geschweiften Klammern zu erstellen, müssen Sie ein Slice-Objekt erstellen:
Ein lesbarer Ansatz:
Während
''.join(reversed('foo'))
es lesbar ist, muss eine String-Methodestr.join
für eine andere aufgerufene Funktion aufgerufen werden, die relativ langsam sein kann. Lassen Sie uns dies in eine Funktion einfügen - wir werden darauf zurückkommen:Performantester Ansatz:
Viel schneller ist die Verwendung eines umgekehrten Slice:
Aber wie können wir dies für jemanden lesbarer und verständlicher machen, der mit Slices oder der Absicht des ursprünglichen Autors weniger vertraut ist? Erstellen wir ein Slice-Objekt außerhalb der Indexnotation, geben Sie ihm einen beschreibenden Namen und übergeben Sie es an die Indexnotation.
Als Funktion implementieren
Um dies tatsächlich als Funktion zu implementieren, denke ich, dass es semantisch klar genug ist, einfach einen beschreibenden Namen zu verwenden:
Und die Nutzung ist einfach:
Was Ihr Lehrer wahrscheinlich will:
Wenn Sie einen Lehrer haben, möchten diese wahrscheinlich, dass Sie mit einer leeren Zeichenfolge beginnen und eine neue Zeichenfolge aus der alten erstellen. Sie können dies mit reiner Syntax und Literalen mithilfe einer while-Schleife tun:
Dies ist theoretisch schlecht, da Zeichenfolgen unveränderlich sind. Jedes Mal, wenn es so aussieht, als würden Sie einen Charakter an Ihre
new_string
Zeichenfolge anhängen , wird theoretisch jedes Mal eine neue Zeichenfolge erstellt. CPython weiß jedoch, wie dies in bestimmten Fällen optimiert werden kann, von denen dieser triviale Fall einer ist.Beste Übung
Theoretisch ist es besser, Ihre Teilzeichenfolgen in einer Liste zu sammeln und später zu verbinden:
Wie wir jedoch in den folgenden Zeitangaben für CPython sehen werden, dauert dies tatsächlich länger, da CPython die Verkettung von Zeichenfolgen optimieren kann.
Timings
Hier sind die Timings:
CPython optimiert die Verkettung von Zeichenfolgen, während andere Implementierungen möglicherweise nicht :
quelle
while
und das Dekrementieren des Index, obwohl dies möglicherweise weniger lesbar ist :for i in range(len(a_string)-1, -1, -1):
. Am meisten finde ich es toll, dass die von Ihnen gewählte Beispielzeichenfolge der einzige Fall ist, in dem Sie sie niemals umkehren müssten und nicht sagen könnten, ob Sie dies getan hätten :)Schnelle Antwort (TL; DR)
Beispiel
Detaillierte Antwort
Hintergrund
Diese Antwort wird bereitgestellt, um die folgenden Bedenken von @odigity auszuräumen:
Problem
Lösung
Tücken
string.reverse()
string.reverse()
zu implementieren , um die Slice-Notation zu vermeiden.print 'coup_ate_grouping'[-4:] ## => 'ping'
print 'coup_ate_grouping'[-4:-1] ## => 'pin'
print 'coup_ate_grouping'[-1] ## => 'g'
[-1]
können einige Entwickler abschreckenBegründung
Python muss einen besonderen Umstand beachten: Eine Zeichenfolge ist ein iterierbarer Typ.
Ein Grund für den Ausschluss einer
string.reverse()
Methode besteht darin, Python-Entwicklern einen Anreiz zu geben, die Kraft dieses besonderen Umstands zu nutzen.Vereinfacht ausgedrückt bedeutet dies einfach, dass jedes einzelne Zeichen in einer Zeichenfolge einfach als Teil einer sequentiellen Anordnung von Elementen bearbeitet werden kann, genau wie Arrays in anderen Programmiersprachen.
Um zu verstehen, wie dies funktioniert, kann das Überprüfen von Beispiel 02 einen guten Überblick bieten.
Beispiel 02
Fazit
Die kognitive Belastung, die mit dem Verständnis der Funktionsweise der Slice-Notation in Python verbunden ist, kann für einige Anwender und Entwickler, die nicht viel Zeit in das Erlernen der Sprache investieren möchten, tatsächlich zu groß sein.
Sobald die Grundprinzipien verstanden sind, kann die Leistungsfähigkeit dieses Ansatzes gegenüber Manipulationsmethoden mit festen Strings jedoch recht günstig sein.
Für diejenigen, die anders denken, gibt es alternative Ansätze wie Lambda-Funktionen, Iteratoren oder einfache einmalige Funktionsdeklarationen.
Auf Wunsch kann ein Entwickler seine eigene string.reverse () -Methode implementieren. Es ist jedoch gut, die Gründe für diesen Aspekt von Python zu verstehen.
Siehe auch
quelle
Die vorhandenen Antworten sind nur dann korrekt, wenn Unicode-Modifikatoren / Graphem-Cluster ignoriert werden. Ich werde später darauf eingehen, aber zuerst einen Blick auf die Geschwindigkeit einiger Umkehralgorithmen werfen:
Sie können sehen, dass die Zeit für das Listenverständnis (
reversed = string[::-1]
) in allen Fällen bei weitem die niedrigste ist (auch nach dem Beheben meines Tippfehlers).String-Umkehrung
Wenn Sie wirklich eine Zeichenfolge im gesunden Menschenverstand umkehren möchten, ist dies viel komplizierter. Nehmen Sie zum Beispiel die folgende Zeichenfolge ( brauner Finger zeigt nach links , gelber Finger zeigt nach oben ). Das sind zwei Grapheme, aber 3 Unicode-Codepunkte. Der zusätzliche ist ein Skin-Modifikator .
Wenn Sie es jedoch mit einer der angegebenen Methoden umkehren, zeigt der braune Finger nach oben und der gelbe Finger nach links . Der Grund dafür ist, dass sich der "braune" Farbmodifikator noch in der Mitte befindet und auf alles angewendet wird, was davor ist. Also haben wir
und
Unicode-Graphem-Cluster sind etwas komplizierter als nur Modifikator-Codepunkte. Zum Glück gibt es eine Bibliothek für den Umgang mit Graphemen :
und daher wäre die richtige Antwort
das ist auch bei weitem das langsamste:
Der Code
quelle
1. Verwenden der Slice-Notation
2. Verwenden der Funktion reverse ()
3. Rekursion verwenden
quelle
RecursionError: maximum recursion depth exceeded while calling a Python object
. Beispiel:rev_string("abcdef"*1000)
Eine weniger verwirrende Sichtweise wäre:
Auf Englisch lautet [-1 :: - 1] wie folgt:
quelle
-1
ist aber immer noch nicht nötig.Kehren Sie eine Zeichenfolge in Python um, ohne reverse () oder [:: - 1] zu verwenden.
quelle
Dies ist auch ein interessanter Weg:
o.ä:
Eine andere "exotischere" Art, Byterarray zu verwenden, das .reverse () unterstützt
wird herstellen:
quelle
quelle
quelle
Dies funktioniert, indem eine Zeichenfolge durchlaufen und ihre Werte in umgekehrter Reihenfolge einer anderen Zeichenfolge zugewiesen werden.
quelle
Hier ist nichts Besonderes:
quelle
Hier ist eine ohne
[::-1]
oderreversed
(zu Lernzwecken):Sie können
+=
Zeichenfolgen verketten, sind jedochjoin()
schneller.quelle
Rekursive Methode:
Beispiel:
quelle
Alle oben genannten Lösungen sind perfekt, aber wenn wir versuchen, eine Zeichenfolge mit der for-Schleife in Python umzukehren, wird dies etwas schwierig. So können wir eine Zeichenfolge mit der for-Schleife umkehren
Ich hoffe, dass dieser für jemanden hilfreich sein wird.
quelle
Das ist mein Weg:
quelle
Es gibt viele Möglichkeiten, eine Zeichenfolge umzukehren, aber ich habe auch eine andere nur zum Spaß erstellt. Ich denke, dieser Ansatz ist nicht so schlecht.
quelle
Diese Klasse verwendet Python Magic-Funktionen, um eine Zeichenfolge umzukehren:
Ausgabe
Referenz
quelle
Mit Python 3 können Sie die Zeichenfolge direkt umkehren, sodass sie keiner anderen Variablen zugewiesen wird. Zuerst müssen Sie die Zeichenfolge in eine Liste konvertieren und dann die
reverse()
Funktion nutzen.https://docs.python.org/3/tutorial/datastructures.html
quelle
Dies ist eine einfache und aussagekräftige Umkehrfunktion, die leicht zu verstehen und zu codieren ist
quelle
Hier ist einfach:
print "loremipsum" [- 1 :: - 1]
und einige logisch:
Ausgabe:
Muspimerol
quelle
Kehren Sie eine Zeichenfolge ohne Python-Magie um.
quelle
Sicher, in Python können Sie sehr ausgefallene 1-Zeilen-Sachen machen. :)
Hier ist eine einfache Allrounder-Lösung, die in jeder Programmiersprache funktionieren kann.
quelle
AUSGABE :
quelle
Sie können die Umkehrfunktion mit einer umfassenden Liste verwenden. Aber ich verstehe nicht, warum diese Methode in Python 3 eliminiert wurde, war unnötig.
quelle
.join
oder etwas, um eine gültige Antwort zu erhalten[c for c in string]
ist gleichbedeutend mitlist(string)
.