Dado que Python string
no se puede cambiar, me preguntaba cómo concatenar una cadena de manera más eficiente.
Puedo escribir así:
s += stringfromelsewhere
o así:
s = []
s.append(somestring)
later
s = ''.join(s)
Mientras escribía esta pregunta, encontré un buen artículo hablando sobre el tema.
http://www.skymind.com/~ocrow/python_string/
Pero está en Python 2.x., entonces, ¿la pregunta sería si algo cambió en Python 3?
Respuestas:
La mejor manera de agregar una cadena a una variable de cadena es usar
+
o+=
. Esto se debe a que es legible y rápido. También son igual de rápidos, el que elijas es cuestión de gustos, el último es el más común. Aquí hay tiempos con eltimeit
módulo:Sin embargo, aquellos que recomiendan tener listas y agregarlas y luego unirse a esas listas, lo hacen porque agregar una cadena a una lista es presumiblemente muy rápido en comparación con extender una cadena. Y esto puede ser cierto, en algunos casos. Aquí, por ejemplo, hay un millón de anexos de una cadena de un carácter, primero a una cadena, luego a una lista:
OK, resulta que incluso cuando la cadena resultante tiene un millón de caracteres, la adición fue aún más rápida.
Ahora intentemos agregar una cadena larga de mil caracteres cien mil veces:
La cadena final, por lo tanto, termina teniendo aproximadamente 100 MB de longitud. Eso fue bastante lento, agregar a una lista fue mucho más rápido. Que ese momento no incluye la final
a.join()
. Entonces, ¿cuánto tiempo tomaría eso?Oups Resulta que incluso en este caso, agregar / unir es más lento.
Entonces, ¿de dónde viene esta recomendación? Python 2?
Bueno, agregar / unir es marginalmente más rápido allí si está usando cadenas extremadamente largas (que generalmente no es así, ¿qué tendría una cadena que tiene 100 MB de memoria?)
Pero el factor decisivo real es Python 2.3. Donde ni siquiera te mostraré los tiempos, porque es tan lento que aún no ha terminado. Estas pruebas de repente toman minutos . Excepto por el append / join, que es tan rápido como en Python posteriores.
Sip. La concatenación de cuerdas fue muy lenta en Python en la edad de piedra. Pero en 2.4 ya no está (o al menos Python 2.4.7), por lo que la recomendación de usar append / join quedó obsoleta en 2008, cuando Python 2.3 dejó de actualizarse, y debería haber dejado de usarlo. :-)
(Actualización: Resulta que cuando hice las pruebas con más cuidado que usar
+
y también+=
es más rápido para dos cadenas en Python 2.3. La recomendación de uso''.join()
debe ser un malentendido)Sin embargo, esto es CPython. Otras implementaciones pueden tener otras preocupaciones. Y esta es solo otra razón por la cual la optimización prematura es la raíz de todo mal. No use una técnica que se supone "más rápida" a menos que primero la mida.
Por lo tanto, la "mejor" versión para hacer la concatenación de cadenas es usar + o + = . Y si eso resulta lento para usted, lo cual es bastante improbable, haga otra cosa.
Entonces, ¿por qué uso mucho agregar / unir en mi código? Porque a veces es más claro. Especialmente cuando lo que deba concatenar juntos debe estar separado por espacios o comas o líneas nuevas.
fuente
Si está concatenando muchos valores, entonces ninguno. Agregar una lista es costoso. Puedes usar StringIO para eso. Especialmente si lo está acumulando en muchas operaciones.
Si ya ha recibido una lista completa de alguna otra operación, simplemente use el
''.join(aList)
De las preguntas frecuentes de Python: ¿Cuál es la forma más eficiente de concatenar muchas cadenas juntas?
Editar: Fui tonto y pegué los resultados al revés, por lo que parecía que agregar a una lista era más rápido que cStringIO. También he agregado pruebas para bytearray / str concat, así como una segunda ronda de pruebas usando una lista más grande con cadenas más grandes. (Python 2.7.3)
ejemplo de prueba de ipython para grandes listas de cadenas
fuente
cStringIO
no existe en Py3. Usar en suio.StringIO
lugar.En Python> = 3.6, la nueva cadena f es una forma eficiente de concatenar una cadena.
fuente
El método recomendado es utilizar append y join.
fuente
Si las cadenas que está concatenando son literales, use la concatenación literal de cadenas
Esto es útil si desea comentar parte de una cadena (como arriba) o si desea usar cadenas sin procesar o comillas triples para parte de un literal, pero no para todo.
Como esto sucede en la capa de sintaxis, utiliza operadores de concatenación cero.
fuente
Escribes esta función
Entonces puedes llamar simplemente a donde quieras
fuente
str_join = lambda *str_list: ''.join(s for s in str_list)
El uso del método de concatenación de cadenas en lugar de '+' es EL PEOR método de concatenación en términos de estabilidad e implementación cruzada, ya que no admite todos los valores. Estándar PEP8 desalienta esto y alienta el uso de format (), join () y append () para uso a largo plazo.
Como se cita en la sección vinculada "Recomendaciones de programación":
fuente
Aunque algo anticuado, Code Like a Pythonista: Idiomatic Python recomienda
join()
más de+
en esta sección . Al igual que PythonSpeedPerformanceTips en su sección sobre concatenación de cadenas , con el siguiente descargo de responsabilidad:fuente
Como @jdi menciona, la documentación de Python sugiere usar
str.join
oio.StringIO
para la concatenación de cadenas. Y dice que un desarrollador debe esperar un tiempo cuadrático+=
en un bucle, a pesar de que hay una optimización desde Python 2.4. Como dice esta respuesta:Mostraré un ejemplo de código del mundo real que ingenuamente se basó en
+=
esta optimización, pero no se aplicó. El siguiente código convierte un iterativo de cadenas cortas en fragmentos más grandes para usar en una API masiva.Este código puede ejecutarse literariamente durante horas debido a la complejidad del tiempo cuadrático. A continuación se presentan alternativas con estructuras de datos sugeridas:
Y un micro-benchmark:
fuente
Puedes hacerlo de diferentes maneras.
Creé este pequeño resumen a través de los siguientes artículos.
fuente
mi caso de uso fue ligeramente diferente. Tuve que construir una consulta donde más de 20 campos eran dinámicos. Seguí este enfoque de usar el método de formato
esto fue comparativamente más simple para mí en lugar de usar + u otras formas
fuente
Puede usar esto (más eficiente) también. ( /software/304445/why-is-s-better-than-for-concatenation )
fuente