Da Pythons string
nicht geändert werden können, habe ich mich gefragt, wie ich einen String effizienter verketten kann.
Ich kann so schreiben:
s += stringfromelsewhere
oder so:
s = []
s.append(somestring)
later
s = ''.join(s)
Während ich diese Frage schrieb, fand ich einen guten Artikel über das Thema.
http://www.skymind.com/~ocrow/python_string/
Aber es ist in Python 2.x., also wäre die Frage, ob sich in Python 3 etwas geändert hat?
Antworten:
Der beste Weg, eine Zeichenfolge an eine Zeichenfolgenvariable anzuhängen, ist die Verwendung von
+
oder+=
. Dies liegt daran, dass es lesbar und schnell ist. Sie sind auch genauso schnell, welche Sie wählen, ist Geschmackssache, die letztere ist die häufigste. Hier sind Timings mit demtimeit
Modul:Diejenigen, die empfehlen, Listen zu haben und an diese anzuhängen und diese dann zu verbinden, tun dies jedoch, da das Anhängen einer Zeichenfolge an eine Liste im Vergleich zum Erweitern einer Zeichenfolge vermutlich sehr schnell ist. Und dies kann in einigen Fällen zutreffen. Hier ist zum Beispiel eine Million Anhänge einer Zeichenfolge mit einem Zeichen, zuerst an eine Zeichenfolge, dann an eine Liste:
OK, es stellt sich heraus, dass das Anhängen auch dann noch schneller war, wenn die resultierende Zeichenfolge eine Million Zeichen lang ist.
Versuchen wir nun, eine tausend Zeichen lange Zeichenfolge hunderttausend Mal anzuhängen:
Die Endzeichenfolge ist daher ungefähr 100 MB lang. Das war ziemlich langsam, das Anhängen an eine Liste war viel schneller. Dass dieses Timing nicht das Finale beinhaltet
a.join()
. Wie lange würde das dauern?Oups. Auch in diesem Fall ist das Anhängen / Verbinden langsamer.
Woher kommt diese Empfehlung? Python 2?
Nun, append / join ist geringfügig es schneller , wenn Sie extrem lange Strings verwenden (was Sie sind in der Regel nicht, was würden Sie eine Zeichenfolge, die 100 MB im Speicher ist?)
Aber der wahre Drahtreifen ist Python 2.3. Wo ich dir nicht einmal die Timings zeigen werde, weil es so langsam ist, dass es noch nicht fertig ist. Diese Tests dauern plötzlich Minuten . Mit Ausnahme des Anhängens / Verbindens, das genauso schnell ist wie unter späteren Pythons.
Jep. Die Verkettung von Strings war in Python in der Steinzeit sehr langsam. Unter 2.4 ist dies jedoch nicht mehr der Fall (oder zumindest Python 2.4.7). Daher wurde die Empfehlung zur Verwendung von Anhängen / Verknüpfen 2008 veraltet, als Python 2.3 nicht mehr aktualisiert wurde und Sie es nicht mehr verwenden sollten. :-)
(Update: Es stellte sich heraus, dass ich die Tests sorgfältiger durchgeführt habe als die Verwendung von
+
und+=
schneller für zwei Zeichenfolgen in Python 2.3. Die Empfehlung zur Verwendung''.join()
muss ein Missverständnis sein.)Dies ist jedoch CPython. Andere Implementierungen können andere Bedenken haben. Und dies ist nur ein weiterer Grund, warum vorzeitige Optimierung die Wurzel allen Übels ist. Verwenden Sie keine Technik, die "schneller" sein soll, es sei denn, Sie messen sie zuerst.
Daher ist die "beste" Version für die Verkettung von Zeichenfolgen die Verwendung von + oder + = . Und wenn sich herausstellt, dass das für Sie langsam ist, was ziemlich unwahrscheinlich ist, dann tun Sie etwas anderes.
Warum verwende ich in meinem Code viel Anhängen / Verbinden? Weil es manchmal tatsächlich klarer ist. Besonders wenn alles, was Sie miteinander verketten sollten, durch Leerzeichen, Kommas oder Zeilenumbrüche getrennt werden sollte.
quelle
Wenn Sie viele Werte verketten, dann keine. Das Anhängen einer Liste ist teuer. Sie können dafür StringIO verwenden. Vor allem, wenn Sie es über viele Operationen aufbauen.
Wenn Sie bereits eine vollständige Liste von einem anderen Vorgang erhalten haben, verwenden Sie einfach die
''.join(aList)
Aus den Python-FAQ: Was ist der effizienteste Weg, um viele Zeichenfolgen miteinander zu verketten?
Bearbeiten: Ich war albern und hatte die Ergebnisse rückwärts eingefügt, sodass es so aussah, als wäre das Anhängen an eine Liste schneller als cStringIO. Ich habe auch Tests für Bytearray / Str Concat sowie eine zweite Testrunde mit einer größeren Liste mit größeren Strings hinzugefügt. (Python 2.7.3)
IPython-Testbeispiel für große Listen von Zeichenfolgen
quelle
cStringIO
existiert nicht in Py3. Verwenden Sieio.StringIO
stattdessen.In Python> = 3.6 ist die neue f-Zeichenfolge eine effiziente Möglichkeit, eine Zeichenfolge zu verketten.
quelle
Die empfohlene Methode ist weiterhin das Anhängen und Verbinden.
quelle
Wenn die Saiten Sie verketten Literalen sind, verwenden Stringliteral Verkettung
Dies ist nützlich, wenn Sie einen Teil einer Zeichenfolge kommentieren möchten (wie oben) oder wenn Sie rohe Zeichenfolgen oder dreifache Anführungszeichen für einen Teil eines Literals verwenden möchten, jedoch nicht für alle.
Da dies auf der Syntaxebene geschieht, werden keine Verkettungsoperatoren verwendet.
quelle
Sie schreiben diese Funktion
Dann können Sie einfach anrufen, wo immer Sie wollen
quelle
str_join = lambda *str_list: ''.join(s for s in str_list)
Die Verwendung der direkten Verkettung von Zeichenfolgen durch '+' ist DIE SCHLECHTESTE Verkettungsmethode in Bezug auf Stabilität und Kreuzimplementierung, da nicht alle Werte unterstützt werden. PEP8-Standard rät davon ab und die Verwendung von format (), join () und append () für die langfristige Verwendung.
Wie aus dem verlinkten Abschnitt "Programmierempfehlungen" zitiert:
quelle
Während etwas veraltet, Code wie ein Pythonista: Idiomatic Python empfiehlt
join()
über die+
in diesem Abschnitt . Ebenso wie PythonSpeedPerformanceTips in seinem Abschnitt zur Verkettung von Zeichenfolgen mit dem folgenden Haftungsausschluss:quelle
Wie @jdi erwähnt, empfiehlt die Python-Dokumentation die Verwendung
str.join
oder dieio.StringIO
Verkettung von Zeichenfolgen. Und sagt, dass ein Entwickler eine quadratische Zeit+=
in einer Schleife erwarten sollte , obwohl es seit Python 2.4 eine Optimierung gibt. Wie diese Antwort sagt:Ich werde ein Beispiel für realen Code zeigen, der sich naiv auf
+=
diese Optimierung stützte , aber nicht zutraf. Der folgende Code konvertiert eine Iterable von kurzen Zeichenfolgen in größere Blöcke, die in einer Bulk-API verwendet werden.Dieser Code kann aufgrund der quadratischen Zeitkomplexität stundenlang literarisch ausgeführt werden. Nachfolgend finden Sie Alternativen mit vorgeschlagenen Datenstrukturen:
Und ein Mikro-Benchmark:
quelle
Sie können auf verschiedene Arten tun.
Ich habe diese kleine Zusammenfassung durch folgende Artikel erstellt.
quelle
Mein Anwendungsfall war etwas anders. Ich musste eine Abfrage erstellen, bei der mehr als 20 Felder dynamisch waren. Ich folgte diesem Ansatz der Formatmethode
Dies war für mich vergleichsweise einfacher, anstatt + oder andere Methoden zu verwenden
quelle
Sie können dies auch (effizienter) verwenden. ( /software/304445/why-is-s-better-than-for-concatenation )
quelle