Da Python & #39; s string
kann & #39; t geändert werden, ich wunderte mich, wie eine Zeichenfolge effizienter zu verketten?
Ich kann es 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 zu diesem Thema.
http://www.skymind.com/~ocrow/python_string/
Aber es ist in Python 2.x., so die Frage wäre, hat etwas in Python 3 geändert?
Wenn Sie viele Werte verketten, dann nicht. Das Anhängen einer Liste ist teuer. Sie können dafür StringIO verwenden. Vor allem, wenn Sie es über eine Menge von Operationen aufbauen.
from cStringIO import StringIO
# python3: from io import StringIO
buf = StringIO()
buf.write('foo')
buf.write('foo')
buf.write('foo')
buf.getvalue()
# 'foofoofoo'
Wenn Sie bereits eine komplette Liste von einer anderen Operation zurückerhalten haben, dann verwenden Sie einfach die Funktion ''.join(aList)
Aus den Python-FAQ: Was ist der effizienteste Weg, um viele Strings miteinander zu verknüpfen?
str und bytes Objekte sind unveränderlich, daher ist die Verkettung von vielen Strings zusammen ist ineffizient, da jede Verkettung ein neues Objekt erzeugt. Im allgemeinen Fall sind die Gesamtlaufzeitkosten quadratisch in der Gesamtlänge der Zeichenkette.
Um viele str-Objekte zu sammeln, empfiehlt es sich, sie in eine Liste zu packen in eine Liste zu packen und str.join() am Ende aufzurufen:
chunks = [] for s in my_strings: chunks.append(s) Ergebnis = ''.join(chunks)
(eine andere einigermaßen effiziente Redewendung ist die Verwendung von io.StringIO)
Um viele Bytes-Objekte zu akkumulieren, ist die empfohlene Redewendung, ein Bytearray-Objekt mit Hilfe von In-Place-Verkettung (dem += Operator) zu erweitern:
Ergebnis = bytearray() for b in my_bytes_objects: result += b
Edit: Ich war dumm und habe die Ergebnisse rückwärts eingefügt, so dass es so aussieht, als ob das Anhängen an eine Liste schneller wäre als cStringIO. Ich habe auch Tests für bytearray/str concat hinzugefügt, sowie eine zweite Runde von Tests mit einer größeren Liste mit größeren Strings. (python 2.7.3)
ipython-Testbeispiel für große Listen von Zeichenketten
try:
from cStringIO import StringIO
except:
from io import StringIO
source = ['foo']*1000
%%timeit buf = StringIO()
for i in source:
buf.write(i)
final = buf.getvalue()
# 1000 loops, best of 3: 1.27 ms per loop
%%timeit out = []
for i in source:
out.append(i)
final = ''.join(out)
# 1000 loops, best of 3: 9.89 ms per loop
%%timeit out = bytearray()
for i in source:
out += i
# 10000 loops, best of 3: 98.5 µs per loop
%%timeit out = ""
for i in source:
out += i
# 10000 loops, best of 3: 161 µs per loop
## Repeat the tests with a larger list, containing
## strings that are bigger than the small string caching
## done by the Python
source = ['foo']*1000
# cStringIO
# 10 loops, best of 3: 19.2 ms per loop
# list append and join
# 100 loops, best of 3: 144 ms per loop
# bytearray() +=
# 100 loops, best of 3: 3.8 ms per loop
# str() +=
# 100 loops, best of 3: 5.11 ms per loop
Obwohl etwas veraltet, empfiehlt Code Like a Pythonista: Idiomatic Python in diesem Abschnitt join()
gegenüber +
. Ebenso wie PythonSpeedPerformanceTips in seinem Abschnitt über String-Verkettung, mit dem folgenden Haftungsausschluss:
Die Genauigkeit dieses Abschnitts ist in Bezug auf spätere Versionen von Python umstritten Versionen von Python. In CPython 2.5 ist die String-Verkettung ziemlich schnell, obwohl dies nicht unbedingt auch für andere Python Implementierungen gilt. Siehe ConcatenationTestCode für eine Diskussion.