Die bloße ersetzen erwähnt durch @steven-rumbalski wird der effizienteste Weg, um dies zu erreichen, aber es ist nicht der einzige Weg.
Hier ist eine andere Lösung mit List Comprehensions. Wenn der Text bereits in eine Liste von Zeilen aufgeteilt wurde, wird dies viel schneller als Laufen join()
, replace()
und splitlines()
text = """A very very very very very very very very very very very very very very very very
long mutiline
string"""
lines = text.splitlines()
indented = [' ' + l for l in lines]
indented[0] = lines[0]
indented = '\n'.join(indented)
Die Liste geändert anstelle werden könnte, aber es gibt ein deutlich Leistungs Kosten einen zweiten im Vergleich mit Variable. Es ist auch mäßig schneller, alle Zeilen einzurücken und dann die erste Zeile in einer anderen Operation auszuwechseln.
Es gibt auch das Modul textwrap
. Ich stimme nicht zu, dass die Verwendung von textwrap für den Einzug unpythonisch ist. Wenn die Linien in einer einzelnen Zeichenfolge mit Zeilenumbrüchen verknüpft sind, ist diese Zeichenfolge in sich eingeschlossen. Einrückung ist eine logische Erweiterung der Textumhüllung, so dass Textumwicklung für mich sinnvoll ist.
Außer dass es langsam ist. Wirklich, wirklich langsam. Wie 15x langsamer.
Python 3 hinzugefügt indent
zu textwrap
, die Einrückung ohne Umwicklung sehr einfach macht. Es gibt sicherlich eine elegantere Art, mit dem Lambda-Prädikat umzugehen, aber das tut genau das, wonach die ursprüngliche Frage gefragt war.
indented = textwrap.indent(text, ' ', lambda x: not text.splitlines()[0] in x)
Hier sind einige timeit
Ergebnisse der verschiedenen Methoden.
>>> timeit.timeit(r"text.replace('\n', '\n ')", setup='text = """%s"""' % text)
0.5123521030182019
Die beiden Liste Verständnis Lösungen:
>>> timeit.timeit(r"indented = [' ' + i for i in lines]; indented[0] = lines[0]", setup='lines = """%s""".splitlines()' % text)
0.7037646849639714
>>> timeit.timeit(r"indented = [lines[0]] + [' ' + i for i in lines[1:]]", setup='lines = """%s""".splitlines()' % text)
1.0310905870283023
Und hier ist das unglückliche textwrap
Ergebnis:
>>> timeit.timeit(r"textwrap.indent(text, ' ', lambda x: not text.splitlines()[0] in x)", setup='import textwrap; text = """%s"""' % text)
7.7950868209591135
Ich dachte, einige jener Zeit die schrecklich ineffizient Prädikat sein könnte, aber auch mit das entfernt, textwrap.indent
ist immer noch mehr als 8 mal langsamer als eine bloße Ersetzung.
>>> timeit.timeit(r"textwrap.indent(text, ' ')", setup='import textwrap; text = """%s"""' % text)
4.266149697010405
Aus der Dokumentation für 'sequential_indent':" Zeichenfolge, die allen Zeilen der umbrochenen Ausgabe vorangestellt wird. " Da nichts eingepackt wird, wird nichts eingerückt. –