In Python entgeht mir das Wo und Wann der Verwendung der Zeichenfolgenverkettung im Vergleich zur Zeichenfolgenersetzung. Ist dies (mehr) eine stilistische Entscheidung und keine praktische, da die Verkettung von Strings große Leistungssteigerungen erfahren hat?
Wie sollte man als konkretes Beispiel mit der Konstruktion flexibler URIs umgehen:
DOMAIN = 'http://stackoverflow.com'
QUESTIONS = '/questions'
def so_question_uri_sub(q_num):
return "%s%s/%d" % (DOMAIN, QUESTIONS, q_num)
def so_question_uri_cat(q_num):
return DOMAIN + QUESTIONS + '/' + str(q_num)
Bearbeiten: Es gab auch Vorschläge zum Verbinden einer Liste von Zeichenfolgen und zum Verwenden der benannten Substitution. Dies sind Varianten des zentralen Themas: Welcher Weg ist der richtige Weg, um es zu welcher Zeit zu tun? Danke für die Antworten!
python
string
string-concatenation
gotgenes
quelle
quelle
Antworten:
Die Verkettung ist laut meinem Computer (erheblich) schneller. Aber stilistisch bin ich bereit, den Preis für die Substitution zu zahlen, wenn die Leistung nicht kritisch ist. Nun, und wenn ich eine Formatierung benötige, muss ich nicht einmal die Frage stellen ... es gibt keine andere Möglichkeit, als Interpolation / Templating zu verwenden.
quelle
Vergessen Sie nicht die benannte Substitution:
quelle
Seien Sie vorsichtig, wenn Sie Zeichenfolgen in einer Schleife verketten! Die Kosten für die Verkettung von Zeichenfolgen sind proportional zur Länge des Ergebnisses. Looping führt Sie direkt in das Land des N-Quadrats. Einige Sprachen optimieren die Verkettung mit der zuletzt zugewiesenen Zeichenfolge, aber es ist riskant, sich auf den Compiler zu verlassen, um Ihren quadratischen Algorithmus auf linear zu optimieren. Verwenden Sie am besten das Grundelement (
join
?), Das eine ganze Liste von Zeichenfolgen verwendet, eine einzelne Zuordnung vornimmt und alle auf einmal verkettet.quelle
"Da die String-Verkettung große Leistungssteigerungen erfahren hat ..."
Wenn es auf die Leistung ankommt, ist dies gut zu wissen.
Leistungsprobleme, die ich gesehen habe, sind jedoch nie auf Zeichenfolgenoperationen zurückzuführen. Ich habe im Allgemeinen Probleme mit E / A, Sortieren und O ( n 2 ) -Operationen sind die Engpässe.
Bis String-Operationen die Leistungsbegrenzer sind, bleibe ich bei Dingen, die offensichtlich sind. Meistens ist dies eine Ersetzung, wenn es sich um eine Zeile oder weniger handelt, eine Verkettung, wenn es sinnvoll ist, und ein Vorlagenwerkzeug (wie Mako), wenn es groß ist.
quelle
Was Sie verketten / interpolieren möchten und wie Sie das Ergebnis formatieren möchten, sollte Ihre Entscheidung bestimmen.
Mit der String-Interpolation können Sie einfach Formatierungen hinzufügen. Tatsächlich funktioniert Ihre String-Interpolationsversion nicht mit Ihrer Verkettungsversion. Es wird tatsächlich ein zusätzlicher Schrägstrich vor dem
q_num
Parameter hinzugefügt. Um dasselbe zu tun, müssten Siereturn DOMAIN + QUESTIONS + "/" + str(q_num)
in dieses Beispiel schreiben .Die Interpolation erleichtert das Formatieren von Zahlen.
"%d of %d (%2.2f%%)" % (current, total, total/current)
wäre in Verkettungsform viel weniger lesbar.Die Verkettung ist nützlich, wenn Sie keine feste Anzahl von Elementen zum String-Ize haben.
Beachten Sie auch, dass Python 2.6 eine neue Version der Zeichenfolgeninterpolation einführt, die als Zeichenfolgenvorlagen bezeichnet wird :
String-Templating soll schließlich die% -Interpolation ersetzen, aber das wird, glaube ich, noch eine ganze Weile nicht passieren.
quelle
Ich habe nur aus Neugier die Geschwindigkeit verschiedener Methoden zur Verkettung / Ersetzung von Zeichenfolgen getestet. Eine Google-Suche zu diesem Thema hat mich hierher gebracht. Ich dachte, ich würde meine Testergebnisse veröffentlichen, in der Hoffnung, dass es jemandem bei der Entscheidung helfen könnte.
... Nach dem Ausführen
runtests((percent_, format_, format2_, concat_), runs=5)
stellte ich fest, dass die% -Methode auf diesen kleinen Zeichenfolgen etwa doppelt so schnell war wie die anderen. Die Concat-Methode war immer die langsamste (kaum). Es gab sehr kleine Unterschiede beim Wechseln der Positionen in derformat()
Methode, aber das Wechseln der Positionen war immer mindestens 0,01 langsamer als bei der regulären Formatmethode.Stichprobe der Testergebnisse:
Ich habe diese ausgeführt, weil ich in meinen Skripten die Verkettung von Zeichenfolgen verwende, und ich habe mich gefragt, wie hoch die Kosten waren. Ich habe sie in verschiedenen Reihenfolgen ausgeführt, um sicherzustellen, dass nichts stört oder dass eine bessere Leistung als erste oder letzte erzielt wird.
"%s" + ("a" * 1024)
Nebenbei bemerkt, ich habe einige längere String-Generatoren in diese Funktionen wie und reguläres Concat war fast dreimal so schnell (1.1 vs 2.8) wie mit den Methodenformat
und%
. Ich denke, es hängt von den Saiten ab und davon, was Sie erreichen wollen. Wenn die Leistung wirklich wichtig ist, ist es möglicherweise besser, verschiedene Dinge auszuprobieren und zu testen. Ich neige dazu, die Lesbarkeit der Geschwindigkeit vorzuziehen, es sei denn, die Geschwindigkeit wird zum Problem, aber das bin nur ich. Also mochte ich mein Kopieren / Einfügen nicht, ich musste 8 Leerzeichen auf alles setzen, damit es richtig aussah. Ich benutze normalerweise 4.quelle
str.format()
undstr.join()
über normale Verkettung. Ich halte auch Ausschau nach 'F-Strings' aus PEP 498 , das kürzlich akzeptiert wurde.str()
Ich bin mir sicher, dass Sie mit den Anrufen, die sich auf die Leistung auswirken, Recht haben. Ich hatte keine Ahnung, wie teuer Funktionsaufrufe damals waren. Ich denke immer noch, dass Tests durchgeführt werden sollten, wenn Zweifel bestehen.join_(): return ''.join(["test ", str(1), ", with number ", str(2)])
scheintjoin
es auch langsamer als der Prozentsatz zu sein.Denken Sie daran, Stilentscheidungen sind praktische Entscheidungen, wenn Sie jemals vorhaben, Ihren Code zu pflegen oder zu debuggen :-) Es gibt ein berühmtes Zitat von Knuth (möglicherweise unter Berufung auf Hoare?): "Wir sollten kleine Effizienzgewinne vergessen, etwa 97% der Zeit: vorzeitige Optimierung ist die Wurzel allen Übels. "
Solange Sie darauf achten, eine O (n) -Aufgabe nicht in eine O (n 2 ) -Aufgabe umzuwandeln, würde ich mich für das entscheiden, was für Sie am einfachsten zu verstehen ist.
quelle
Ich benutze Substitution, wo immer ich kann. Ich verwende die Verkettung nur, wenn ich einen String in einer for-Schleife aufbaue.
quelle
In diesem Fall ist es eigentlich richtig, Pfade zu verwenden
os.path.join
. Keine Verkettung oder Interpolation von Zeichenfolgenquelle