Welches ist die bevorzugte Methode zum Verketten eines Strings in Python?



Answers

Wenn Sie viele Werte verketten, dann auch nicht. Das Anhängen einer Liste ist teuer. Sie können StringIO dafür verwenden. Vor allem, wenn Sie es über viele Operationen hinweg 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 vollständige Liste von einem anderen Vorgang erhalten haben, verwenden Sie einfach die ''.join(aList)

Aus der Python-FAQ: Was ist der effizienteste Weg, um viele Strings miteinander zu verketten?

str- und bytes-Objekte sind unveränderlich, daher ist das Verketten vieler Strings ineffizient, da jede Verkettung ein neues Objekt erzeugt. Im allgemeinen Fall sind die gesamten Laufzeitkosten quadratisch in der gesamten Stringlänge.

Um viele str-Objekte zu akkumulieren, empfiehlt es sich, sie in eine Liste aufzunehmen und am Ende str.join () aufzurufen:

chunks = []
for s in my_strings:
    chunks.append(s)
result = ''.join(chunks)

(Ein anderes vernünftiges Idiom ist io.StringIO)

Um viele Byte-Objekte zu akkumulieren, wird empfohlen, ein Bytearray-Objekt unter Verwendung der direkten Verkettung (der Operator + =) zu erweitern:

result = bytearray()
for b in my_bytes_objects:
    result += b

Edit: Ich war albern und hatte die Ergebnisse rückwärts eingefügt, so dass es aussieht, als wäre das Anhängen an eine Liste schneller 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 String-Listen

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
Question

Da Pythons string nicht geändert werden kann, habe ich mich gefragt, wie man 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, der über das Thema sprach.

http://www.skymind.com/~ocrow/python_string/

Aber es ist in Python 2.x., also hat sich die Frage etwas in Python 3 geändert?




Sie schreiben diese Funktion

def str_join(*args):
    return ''.join(map(str, args))

Dann können Sie einfach anrufen, wo immer Sie wollen

str_join('Pine')  # Returns : Pine
str_join('Pine', 'apple')  # Returns : Pineapple
str_join('Pine', 'apple', 3)  # Returns : Pineapple3



Wenn die Zeichenfolgen, die Sie verketten, Literale sind, verwenden Sie die String-Literalverkettung

re.compile(
        "[A-Za-z_]"       # letter or underscore
        "[A-Za-z0-9_]*"   # letter, digit or underscore
    )

Dies ist nützlich, wenn Sie einen Teil einer Zeichenkette kommentieren möchten (wie oben) oder wenn Sie für einen Teil eines Literals, aber nicht für alle, rohe Strings oder Triple-Anführungszeichen verwenden möchten.

Da dies in der Syntaxschicht geschieht, werden keine Verkettungsoperatoren verwendet.




Die Verwendung der In-Place-String-Verkettung durch '+' ist die WORST-Methode der Verkettung in Bezug auf Stabilität und Cross-Implementierung, da sie nicht alle Werte unterstützt. Der PEP8-Standard entmutigt dies und regt die Verwendung von format (), join () und append () zur langfristigen Verwendung an.




Related