Tā kā Pythons
string` nevar mainīt, man bija jautājums, kā efektīvāk savienot virkni?
Es varu uzrakstīt, piemēram, tā:
s += stringfromelsewhere
vai šādi:
s = []
s.append(somestring)
later
s = ''.join(s)
Rakstot šo jautājumu, es atradu labu rakstu par šo tēmu.
http://www.skymind.com/~ocrow/python_string/
Bet tas ir Python 2.x., tāpēc jautājums būtu, vai kaut kas mainījies Python 3?
Ja apvienojat daudz vērtību, tad ne. Saraksta pievienošana ir dārga. Tam var izmantot StringIO. Īpaši, ja to veidojat, veicot daudz operāciju.
from cStringIO import StringIO
# python3: from io import StringIO
buf = StringIO()
buf.write('foo')
buf.write('foo')
buf.write('foo')
buf.getvalue()
# 'foofoofoo'
Ja jums jau ir pilns saraksts, kas saņemts no kādas citas operācijas, tad vienkārši izmantojiet ''.join(aList)
.
No Python FAQ: Kāds ir visefektīvākais veids, kā savienot kopā daudzas virknes?.
objekti str un baiti ir nemainīgi, tāpēc daudzu objektu savienošana ir nemainīga. virknes kopā ir neefektīva, jo katra apvienošana rada jaunu virkni. objektu. Vispārējā gadījumā kopējās izpildes laika izmaksas ir kvadrātiskas. kopējam virknes garumam.
Lai uzkrātu daudzus str objektus, ieteicamā idioma ir izvietot tos sarakstā un beigās izsaukt str.join():
chunks = [] for s in my_strings: chunks.append(s) result = ''.join(chunks)
(cita pietiekami efektīva idioma ir izmantot io.StringIO)
Lai uzkrātu daudz baitu objektu, ieteicamā idioma ir paplašināt a bytearray objektu, izmantojot savienošanu uz vietas (operators +=):
result = bytearray() for b in my_bytes_objects: result += b
Edit: Es biju muļķīgs un rezultātus ielīmēju atpakaļ, lai izskatās, ka pievienošana sarakstam ir ātrāka nekā cStringIO. Esmu pievienojis arī testus bytearray/str concat, kā arī otru testu kārtu, izmantojot lielāku sarakstu ar lielākām virknēm. (python 2.7.3)
ipython testa piemērs lieliem virkņu sarakstiem
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
Lai gan nedaudz novecojusi, Code Like a Pythonista: Idiomatic Python iesaka join()
, nevis +
šajā sadaļā. Tāpat kā PythonSpeedPerformanceTips sadaļā par virknes savienošanu, ar šādu atrunu:
Šīs sadaļas precizitāte ir apšaubāma attiecībā uz vēlāku. Python versijām. CPython 2.5 versijā virkņu savienošana ir diezgan precīza. ātra, lai gan tas var nebūt attiecināms arī uz citām Python implementācijām. Apspriedes par to skatiet ConcatenationTestCode.