¿Realmente conoces los Strings en Python?



@eduardo_gpg

Número de visitas 1701

Tiempo de lectura 4 min

31 Mayo 2020

Los strings en Python son sin duda uno de los objetos más interesantes que posee el lenguaje. Un String como sabemos no es más que un arreglo de caracteres, los cuales ya poseen un orden y una posición establecida. Veamos un par de ejemplos.

mensaje = 'Hola mundo'

cantidad_caracteres = len(mensaje)

>>> print( cantidad_caracteres)
7

>>> print( mensaje[0] ) # Primer carácter
H

>>> print( mensaje[ cantidad_caracteres - 1 ] ) # Último carácter
o

En este caso mi variable mensajes posee una longitud de 7, 7 caracteres(Hola mundo). El espacio, por supuesto, es tomado en cuenta. 😃

Al igual que una lista o una tupla, los strings en Python se rigen por la regla de los índices. En este caso a cada carácter le pertenece una posición dentro del string. Para nosotros acceder a un carácter en especial, basta con apoyarnos de corchetes y el índice del cual queremos conocer su valor .

>>> print( mensaje[0] ) # Primer carácter
H

De igual forma, es importante mencionar, en Python los strings son objetos inmutables. Una vez nosotros definamos un string, este no podrá ser modificado en tiempo de ejecución. Si ejecutamos el siguiente ejemplo obtendremos como resultado un error.

mensaje = 'Hola mundo'  
mensaje[1] = 'O'  

TypeError   Traceback (most recent call last)
<ipython-input-72-3d27ce0e62a1> in <module>
----> 1 mensaje[1] = 'O'

TypeError: 'str' object does not support item assignment

Si bien es cierto un string no puede ser modificado, es posible crear nuevos strings a partir de otros.

Veamos un par de ejemplos.

>>> mensaje = 'Hola'
>>> nombre = 'Cody'

>>> nuevo_mensaje = mensaje + ' ' + Cody
>>> print(nuevo_mensaje)
Hola Cody

En este caso, estoy creando un nuevo string a partir de tres ya existentes (la variable mensaje, el espacio y la variable nombre).

Veamos otro ejemplo.

>>> nombre = 'cody'
>>> titulo = nombre[0].upper() + nombre[1:]

>>> print(titulo)
>>> Cody

Para este ejemplo creo un nuevo string utilizando la variable nombre como base. La única modificación ocurren en el primer carácter (Convertimos a mayúsculas).

Hasta aquí muy probablemente ya conocías todas estas cualidades de los strings, sin embargo ¿Habías escuchado hablar de string interning ? 😲 ¿No? bueno, no te preocupes, en esta ocasión me gustaría explicar como Python maneja la memoria al momento de crear objetos inmutables, tal y como son los objetos de tipo string. Es algo bastante interesante, y sin duda puede llegar hacernos de mucha utilidad.

Bien, Sin más preámbulos, comencemos.

String interning

Comencemos con un par de ejemplos. ¿Cual crees que sería el resultado de ejecutar los siguiente script?

>>> a = 'Cody'
>>> b = 'Cody'

>>> a is b
>>> c = 'Cody!' 
>>> d = 'Cody!' 

>>> c is d

Recordemos que la palabra reservada is nos permite conocer si dos objetos son el mismo.

Tomate tu tiempo. Quizás el resultado sea ¿True True? ¿False False? ¿True False? o ¿False True? no ejecutes nada, simplemente analísalo.

Bien, aquí va la respuesta. Si ejecutamos ambos scripts obtendremos como resultado True y False. ¿Sorprendido? ¿A qué se debe esto? Deja te explico. 😋

En Python al crear objetos inmutables, como lo son los strings, habrá ocasiones en las cuales múltiples variables hagan referencia a un mismo espacio en memoria.

Esto claramente se puede con en el primer ejemplo.

>> a is b
True

Si examinamos el id de cada objeto estos serán los mismos.

>>> id(a) 
4365205152

>>> id(b) 
4365205152

A esto se le conoce como String interning, al proceso de almacenar una sola copia de un string en memoria; y Pytohn lo implemente con la finalidad de ahorrar memoria y evitar crear nuevos objetos de forma innecesaria. Con esto en mente, el primer resultado tiene todo el sentido del mundo, a is b True.

Cuando la variable a es creada, Python confirma que el String 'Cody' no se encuentra almacenado en memoria, así que se procede a hacerlo, sin embargo, cuando la variable b es creada, al interprete confirmar que 'Cody' ya se encuentra en memoria, asigna una referencia a la variable b, evitando reservar espacio en memoria de un valor previamente ya almacenado.

Esto quiere decir que, cuando creamos 2 o más strings con el mismo valor, solo un string es realmente almacenado en memoria; el restante son variables que apuntan al mismo espacio en memoria.

Veamos otro ejemplo.

>>> a = 'PyWombat'
>>> b = 'PyWombat'

>>> a is b
True

Ok, hasta aquí todo bien, con la finalidad de ahorrar espacio, Python solo almacena un string en memoria, y el restante son referencias, Sin embargo ¿Por qué en el segundo ejemplo el resultado es False? Bien, esto se debe a que Python posee "ciertas reglas" para que un objeto pueda, o no ser interning (O internado, por su traducción al español, aun que esto no suena muy bien).

En el caso de los strings, para que estos puedan almacenados una sola vez, estos debe de cumplir con por lo menos una de las siguientes reglas.

  • Todos los strings longitud 0 o longitud 1 serán interning.
  • Todos los strings cuya longitud sea mayor a 4096 caracteres no sera candidato a interning.
  • Si un string contiene cualquier carácter que no sea una letra ASCII, un dígito o un guión bajo, no será Interning.

Con esto en mente el segundo ejemplo ya comienza a tomar sentido. El resultado es False por el signo de admiración (!) 'Cody!' .

Veamos un par de ejemplos para que nos más en claro.

En este caso todas nuestras variables posee una longitud de 1.

>>> a = 'a'
>>> b = 'b'

>>> c = '!'
>>> d = '!'

>>> a is b 
True

>>> c is d
True

Para este nuevo ejemplo, los strings cuentan con un guión bajo.

>>> usuario1 = 'codigo_facilito'
>>> usuario2 =  'codigo_facilito'

>>> usuario1 is usuario2
True

Si colocamos un espacio en el string, este no podrá ser cacheado en memoria.

>>> a = 'Hola mundo'
>>> b = 'Hola mundo'

>>> a is b
False

### Integer Interning

El interning no solo funciona para los string. Ya que como mencionamos anteriormente, esto se utiliza sobre todos los objetos inmutables, y los enteros no son la excepción.

En Python al nosotros declarar cualquier número entero que comprenda del -5 al 256 este será cacheado en memoria y serán utilizado como referencia.

>>> number1 = 120
>>> number2 = 120

>>> number1 is number2
True

¿Por qué utilizar interning?

Ahora pasemos a la pregunta clave ¿Por qué es importante conocer los interning? La respuesta es sencilla, por temas de optimización.

Al utilizar interning no solo estaremos ahorrando espacio en memoria, si no que las comparaciones entre objetos serán mucho más eficientes. Por ejemplo, al comparar dos strings, Python no recorrerá carácter por carácter para conocer si ambos objetos son el mismo, en lugar de ello comparará su espacio en memoria. Si ambos objetos comparten el mismo espacio en memoria entonces se concluye que son el mismo objeto.

Si bien es cierto todo este conocimiento no influye en el cómo vamos a codificar, si es importante conocerlo para realizar programas cada vez eficientes, y por supuesto, profesionales. 🍻


¿El contenido te resulto de ayuda?

Para poder dejar tu opinión es necesario ser un usuario autenticado. Login

Rafaelaquino

Gracias por compartir tus conocimientos con la comunidad. Feliz día.

Rafaelaquino

#Otra forma, para el último caracter de un string

print(mensaje[-1])

Más Tips y Ejercicios 🐍

Adquiere una subscripción PyWombat por tan solo $3 USD. al mes.

Conoce los beneficios de ser usuario premium:
Niveles desbloqueados: Ten accesos a todos los niveles de ejercicios. 🔓
Nuevo límite: Incrementa tu límite de ejercicios por semana. 🚀
Contenido único: Recibe semanalmente recursos exclusivos de Python (Videos, Artículos y Capitulos del libro PyWombat, comienza como desarrollador Python. 🐍