tipos separar reemplazar por palabra letras funcion concatenar caracteres caracter python string append

separar - ¿Cómo agrego una cadena a otra en Python?



string en python (9)

Quiero una manera eficiente de agregar una cadena a otra en Python.

var1 = "foo" var2 = "bar" var3 = var1 + var2

¿Hay algún buen método incorporado para usar?


Básicamente, no hay diferencia. La única tendencia consistente es que Python parece estar disminuyendo su velocidad con cada versión ... :(

Lista

%%timeit x = [] for i in range(100000000): # xrange on Python 2.7 x.append(''a'') x = ''''.join(x)

Python 2.7

1 bucle, el mejor de 3: 7.34 s por bucle

Python 3.4

1 bucle, el mejor de 3: 7.99 s por bucle

Python 3.5

1 bucle, el mejor de 3: 8.48 s por bucle

Python 3.6

1 bucle, el mejor de 3: 9.93 s por bucle

Cuerda

%%timeit x = '''' for i in range(100000000): # xrange on Python 2.7 x += ''a''

Python 2.7 :

1 bucle, el mejor de 3: 7.41 s por bucle

Python 3.4

1 bucle, el mejor de 3: 9.08 s por bucle

Python 3.5

1 bucle, el mejor de 3: 8,82 s por bucle

Python 3.6

1 bucle, el mejor de 3: 9.24 s por bucle


No lo hagas

Es decir, para la mayoría de los casos es mejor que genere toda la cadena de una vez en lugar de agregarla a una cadena existente.

Por ejemplo, no hagas: obj1.name + ":" + str(obj1.count)

En su lugar: use "%s:%d" % (obj1.name, obj1.count)

Eso será más fácil de leer y más eficiente.


No optimices prematuramente Si no tiene motivos para creer que hay un cuello de botella de velocidad causado por las concatenaciones de cadenas, simplemente quédese con + y += :

s = ''foo'' s += ''bar'' s += ''baz''

Dicho esto, si apuntas a algo como StringBuilder de Java, el lenguaje canónico de Python es agregar elementos a una lista y luego usar str.join para concatenarlos al final:

l = [] l.append(''foo'') l.append(''bar'') l.append(''baz'') s = ''''.join(l)


Realmente depende de su aplicación. Si recorres cientos de palabras y deseas .join() a una lista, .join() es mejor. Pero si estás juntando una oración larga, es mejor que uses += .


Si necesita realizar muchas operaciones de StringIO para crear una cadena grande, puede usar StringIO o cStringIO. La interfaz es como un archivo. Es decir: write para agregarle texto.

Si solo estás agregando dos cadenas, simplemente usa + .


Si solo tiene una referencia a una cadena y concatena otra cadena hasta el final, CPython ahora hace un caso especial e intenta extender la cadena en su lugar.

El resultado final es que la operación se amortiza O (n).

p.ej

s = "" for i in range(n): s+=str(i)

solía ser O (n ^ 2), pero ahora es O (n).

De la fuente (bytesobject.c):

void PyBytes_ConcatAndDel(register PyObject **pv, register PyObject *w) { PyBytes_Concat(pv, w); Py_XDECREF(w); } /* The following function breaks the notion that strings are immutable: it changes the size of a string. We get away with this only if there is only one module referencing the object. You can also think of it as creating a new string object and destroying the old one, only more efficiently. In any case, don''t use this if the string may already be known to some other part of the code... Note that if there''s not enough memory to resize the string, the original string object at *pv is deallocated, *pv is set to NULL, an "out of memory" exception is set, and -1 is returned. Else (on success) 0 is returned, and the value in *pv may or may not be the same as on input. As always, an extra byte is allocated for a trailing /0 byte (newsize does *not* include that), and a trailing /0 byte is stored. */ int _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize) { register PyObject *v; register PyBytesObject *sv; v = *pv; if (!PyBytes_Check(v) || Py_REFCNT(v) != 1 || newsize < 0) { *pv = 0; Py_DECREF(v); PyErr_BadInternalCall(); return -1; } /* XXX UNREF/NEWREF interface should be more symmetrical */ _Py_DEC_REFTOTAL; _Py_ForgetReference(v); *pv = (PyObject *) PyObject_REALLOC((char *)v, PyBytesObject_SIZE + newsize); if (*pv == NULL) { PyObject_Del(v); PyErr_NoMemory(); return -1; } _Py_NewReference(*pv); sv = (PyBytesObject *) *pv; Py_SIZE(sv) = newsize; sv->ob_sval[newsize] = ''/0''; sv->ob_shash = -1; /* invalidate cached hash value */ return 0; }

Es bastante fácil de verificar empíricamente.

$ python -m timeit -s"s=''''" "for i in xrange(10):s+=''a''" 1000000 loops, best of 3: 1.85 usec per loop $ python -m timeit -s"s=''''" "for i in xrange(100):s+=''a''" 10000 loops, best of 3: 16.8 usec per loop $ python -m timeit -s"s=''''" "for i in xrange(1000):s+=''a''" 10000 loops, best of 3: 158 usec per loop $ python -m timeit -s"s=''''" "for i in xrange(10000):s+=''a''" 1000 loops, best of 3: 1.71 msec per loop $ python -m timeit -s"s=''''" "for i in xrange(100000):s+=''a''" 10 loops, best of 3: 14.6 msec per loop $ python -m timeit -s"s=''''" "for i in xrange(1000000):s+=''a''" 10 loops, best of 3: 173 msec per loop

Sin embargo, es importante tener en cuenta que esta optimización no es parte de la especificación de Python. Es solo en la implementación de cPython que yo sepa. Las mismas pruebas empíricas en pypy o jython, por ejemplo, pueden mostrar el rendimiento anterior de O (n ** 2).

$ pypy -m timeit -s"s=''''" "for i in xrange(10):s+=''a''" 10000 loops, best of 3: 90.8 usec per loop $ pypy -m timeit -s"s=''''" "for i in xrange(100):s+=''a''" 1000 loops, best of 3: 896 usec per loop $ pypy -m timeit -s"s=''''" "for i in xrange(1000):s+=''a''" 100 loops, best of 3: 9.03 msec per loop $ pypy -m timeit -s"s=''''" "for i in xrange(10000):s+=''a''" 10 loops, best of 3: 89.5 msec per loop

Hasta aquí todo bien, pero entonces,

$ pypy -m timeit -s"s=''''" "for i in xrange(100000):s+=''a''" 10 loops, best of 3: 12.8 sec per loop

Ay aún peor que cuadrático. Entonces, pypy está haciendo algo que funciona bien con cadenas cortas, pero que funciona mal para cadenas más grandes.


añadir cadenas con la función __add__

str = "Hello" str2 = " World" st = str.__add__(str2) print(st)

Salida

Hello World


a=''foo'' b=''baaz'' a.__add__(b) out: ''foobaaz''


str1 = "Hello" str2 = "World" newstr = " ".join((str1, str2))

Eso une str1 y str2 con un espacio como separadores. También puede hacer "".join(str1, str2, ...) . str.join() toma un iterable, por lo que tendrías que poner las cadenas en una lista o una tupla.

Eso es tan eficiente como se puede hacer con un método incorporado.