Python – Troceando y recomponiendo strings

Objetivo: presentar los métodos split() y join() para descomponer y recomponer strings, respectivamente.

Voy a enseñarte un sencillo truco de magia que puedes agregar a tu kit de herramientas en Python y que sin duda te será de gran utilidad en tu día a día como programador.

Para ello voy a necesitar tu colaboración. Confía en mí y déjame un billete, el de más valor que tengas. Ese mismo de color púrpura, por ejemplo, servirá.

>>> billete = 'Esto es un billete de 500 euros'

(No he visto un billete de 500 euros en mi vida. He tenido que recurrir a la wikipedia para consultar su color).

Ahora voy a romperlo delante de tus narices:

>>> trocitos_de_billete = billete.split()
>>> trocitos_de_billete
['Esto', 'es', 'un', 'billete', 'de', '500', 'euros']

O al menos lo era.

El método split(), aplicado a un string, crea una lista en la que cada elemento es una palabra del string. Como si de una butifarra se tratase, split() ha troceado la cadena de caracteres en sus palabras individuales y las ha guardado en una lista.

El modo de reconocer donde acaba y empieza una palabra es obvio: no tiene más que localizar cada espacio en blanco de separación y romper ahí.

Lo interesante de split() es que no le importa si hay más espacios en blancos de los debidos:

>>> dicho = 'Las palabras se las lleva el              viento'
>>> dicho.split()
['Las', 'palabras', 'se', 'las', 'lleva', 'el', 'viento']

Ni siquiera si esos espacios son tabuladores o saltos de línea:

>>> misterio = 'Dónde\testán\t\tlas llaves\nmatarile\nmatarile'
>>> print(misterio)
Dónde  están    las llaves
matarile
matarile
>>> 
>>> misterio.split()
['Dónde', 'están', 'las', 'llaves', 'matarile', 'matarile']

Para él es como si fueran un único espacio.

El método split() nos permite ciertas opciones de juego. Podemos, por ejemplo, indicar que el separador sea otro en lugar del espacio en blanco:

>>> gazpacho = 'tomate-pepino-pimiento-aceite-vinagre'
>>> gazpacho.split('-')
['tomate', 'pepino', 'pimiento', 'aceite', 'vinagre']

Algo que no tiene por qué limitarse a un único carácter:

>>> extensiones = '201abc202abc203'
>>> extensiones.split('abc')
['201', '202', '203']

También podemos precisar el número de veces que meteremos el cuchillo:

>>> python = '1 Python Programas Generador de claves aleatorias'
>>> python.split(' ', 3)
['1', 'Python', 'Programas', 'Generador de claves aleatorias']

Observa que, al necesitar el segundo parámetro, me he visto obligado a indicar el primero, el separador.

Pero podría haberlo obviado del siguiente modo:

>>> python.split(maxsplit = 3)
['1', 'Python', 'Programas', 'Generador de claves aleatorias']

Planteemos ahora el problema inverso: dada una lista de strings, fusionarla en una única cadena empleando determinado carácter como separador.

Los objetos de tipo string disponen de un método que logra precisamente eso: join().

Percátate de una sutileza en la frase anterior: he dicho que el método join() es propio del tipo string y no del tipo list. Por lo tanto no se puede aplicar sobre una lista sino sobre un string.

Entonces, si disponemos de dos elementos, la lista que queremos concatenar y el separador, ¿sobre cuál de ellos aplicaremos el join()? Sobre el separador, no hay otra opción, facilitando como argumento la lista.

>>> estaciones = ['Primavera', 'Verano', 'Otoño', 'Invierno']
>>> ' '.join(estaciones)
'Primavera Verano Otoño Invierno'

El separador puede ser cualquier string, obviamente:

>>> ' <---> '.join(estaciones)
'Primavera <---> Verano <---> Otoño <---> Invierno'

Volvamos entonces a nuestro truco de magia, con el billete de quinientos euros destrozado:

>>> trocitos_de_billete
['Esto', 'es', 'un', 'billete', 'de', '500', 'euros']

Reconstruirlo es tan simple como esto:

>>> billete_reconstruido = ' '.join(trocitos_de_billete)
>>> billete_reconstruido
'Esto es un billete de 500 euros'

Naturalmente, todo ha sido un truco. Aunque me vieras romper el billete delante de tus narices, eso nunca sucedió. El billete original, como en todos los buenos trucos, nunca sufrió daño alguno:

>>> billete
'Esto es un billete de 500 euros'

Javier Montero Gabarró


Python – Troceando y recomponiendo strings


El texto de este artículo se encuentra sometido a una licencia Creative Commons del tipo CC-BY-NC-ND (reconocimiento, no comercial, sin obra derivada, 3.0 unported)


El Club del Autodidacta


Consulta el índice completo de artículos relacionados con Python.

Python: MAYÚSCULAS, minúsculas y ViCeVeRsA

Objetivo: presentar los métodos que ofrece Python para la gestión de mayúsculas y minúsculas en strings.

Entre nuestro repertorio de técnicas pythonistas no pueden faltar las dedicadas al tratamiento de cadenas de caracteres. Es raro el programa que no las utiliza, de modo que cuanto antes las conozcas mejor será para ti. Hoy hablaremos de un subconjunto de ellas especializadas en el trasiego de letras mayúsculas y minúsculas.

Un problema común cuando un programa recibe texto es su normalización para poder realizar después un tratamiento correcto. Por ejemplo, imagínate que estás requiriendo el DNI del usuario. Tu programa debe ser capaz de reconocer que dos DNI con los mismos números y la misma letra final son realmente el mismo, se escriba la letra en mayúsculas o minúsculas.

Juguemos un rato con el intérprete interactivo. Consideremos, por ejemplo, la siguiente cadena de texto:

>>> a = 'La casa de la Pradera'

Para hacer que un string contenga sólo letras minúsculas disponemos del método lower():

>>> a.lower()
'la casa de la pradera'

Esto crea una copia del objeto con minúsculas. Recuerda que los strings son inmutables y los métodos que se apliquen sobre ellos nunca modificarán el objeto original. Si no tienes muy claro el misterio de la inmutabilidad en Python, te recomiendo que leas el artículo al que apunta el enlace.

La operación contraria, la conversión a mayúsculas, se obtiene mediante el método upper():

>>> a.upper()
'LA CASA DE LA PRADERA'

El método capitalize() devuelve un string en el que solo la primera letra estará escrita en mayúsculas:

>>> a.capitalize()
'La casa de la pradera'

Aunque pueda resultar extravagante, a veces es necesaria la inversión de tipos: lo que está en mayúsculas pasarlo a minúsculas, y viceversa. El método swapcase() resuelve el problema:

>>> a.swapcase()
'lA CASA DE LA pRADERA'

El método title() escribe en mayúsculas solo la primera letra de cada palabra, como en los títulos:

<code>>>> a.title()
'La Casa De La Pradera'

Para otro tipo de conversiones será necesario recurrir a algo más de código. Considera el siguiente problema: dada una palabra cualquiera, transformarla para que el tercer carácter esté escrito en letras mayúsculas.

Supongamos, por ejemplo, la siguiente cadena de caracteres:

>>> a = 'pradera'

Pretendemos que el tercer carácter esté en mayúsculas.

Este intento de conversión fallará debido a la inmutabilidad de los strings, que no permiten la modificación in-situ:

>>> a[2] = a[2].upper()   # El tercer carácter tiene por índice 2
Traceback (most recent call last):
  File "<pyshell#26>", line 1, in <module>
    a[2] = a[2].upper()   # El tercer carácter tiene por índice 2
TypeError: 'str' object does not support item assignment

Para resolver el problema podemos recurrir a la creación de substrings mediante la técnica de slicing, que hemos utilizado ya en diversas ocasiones:

>>> a = a[:2] + a[2].upper() + a[3:]
>>> a
'prAdera'

El primer término de la concatenación contiene una copia de a desde el primer elemento (índice cero) hasta el tercero (índice 2) sin incluir. El segundo es una copia del tercer carácter de a. Finalmente, el último contiene lo restante de la cadena, es decir, desde el cuarto elemento (índice 3) hasta el final.

Actividad propuesta: construye una función que acepte como parámetros un string y un número y devuelva un string, con el carácter correspondiente al índice, facilitado por el número, en mayúsculas.

Para finalizar, es útil saber si un string está escrito completamente en letras minúsculas o en mayúsculas. Para ello disponemos de los métodos islower() e isupper(), respectivamente.

>>> a = 'pradera'
>>> a.islower()
True
>>> b = 'PIMiENTO'
>>> b.isupper()
False

El método islower() devuelve True cuando todas las letras están en minúsculas y al menos hay un carácter alfabético. Esto otro, por ejemplo, resultaría False, al no existir ninguna letra en el string:

>>> c = ':;..'
>>> c.islower()
False

En cambio, esto sería True:

>>> d = ':;.a'
>>> d.islower()
True

Lo mismo es aplicable a isupper(): devuelve True cuando todas las letras están en mayúsculas y al menos hay una letra en la cadena.

Son muchos los métodos de los que dipone el objeto string y es tu deber conocerlos. Agruparlos en pequeños bloques, como hemos hoy, facilita su aprendizaje.

Javier Montero Gabarró


Python: MAYÚSCULAS, minúsculas y ViCeVeRsA


El texto de este artículo se encuentra sometido a una licencia Creative Commons del tipo CC-BY-NC-ND (reconocimiento, no comercial, sin obra derivada, 3.0 unported)


El Club del Autodidacta


Consulta el índice completo de artículos relacionados con Python.

Python – Capítulo 34: Especificaciones de conversión

Objetivo: Conocer otras especificaciones de conversión para el formato de strings empleando el operador de interpolación (%).

En el capítulo 33 presentamos el operador de interpolación (%), una de las maneras que tiene Python para formatear cadenas de caracteres. A la izquierda del operador figuraba un string en el que insertábamos determinadas especificaciones de conversión; a la derecha, una tupla (o un elemento simple) con los valores que sustituirían a aquellas.

Vimos, además, el especificador de conversión %d para su sustitución por un número entero. Este es semejante a %i y puedes usar uno u otro indistintamente (d es de decimal, entero decimal; la i es de integer).

Vamos a presentar algunos más…

Si, en vez de un entero decimal, quieres convertir el valor a octal, dispones de la especificación %o. Observa la conversión en el siguiente ejemplo:

>>> x=15324
>>> print("%d expresado en octal es %o" % (x, x))
15324 expresado en octal es 35734

Para pasar a hexadecimal puedes elegir entre %x o %X, dependiendo de si lo quieres en mayúsculas o minúsculas:

>>> print ("En hexadecimal es %x, o %X expresado en mayúsculas" % (x, x))
En hexadecimal es 3bdc, o 3BDC expresado en mayúsculas

Para números reales dispones de %f (de float):

>>> x=143.25
>>> print("El valor de x es %f" % x)
El valor de x es 143.250000

No te preocupes ahora por el número de decimales después del punto, pues hablaremos de eso en su momento.

Los números reales también puedes expresarlos en notación científica:

>>> print("que es lo mismo que %e, o bien %E con la E mayúscula" % (x, x))
que es lo mismo que 1.432500e+02, o bien 1.432500E+02 con la E mayúscula

Observa que utilizamos %e o %E dependiendo de si preferimos la e en minúsculas o mayúsculas.

Mira este otro curioso ejemplo con %g:

>>> print("Estas variables son, respectivamente, %g, %g, %g, %g y %g" % (a,b,c,d,e))
Estas variables son, respectivamente, 0.5, 0.05, 0.005, 0.0005 y 5e-05

Lo que está sucediendo es que la especificación %g (de general) representa los números reales inteligentemente. Sólo emplea notación científica cuando el exponente es inferior a -4; en caso contrario los representa en formato decimal. Si quieres la E en mayúsculas, usa %G.

Para representar un carácter simple empleamos %c. Podemos facilitar el carácter así, tal cual, o como número entero, en cuyo caso se efectuará la conversión al carácter correspondiente a ese código en Unicode:

>>> c1='A'
>>> c2=65
>>> print("c1 y c2 son, respectivamente, %c y %c." % (c1, c2))
c1 y c2 son, respectivamente, A y A.

Para interpolar un string disponemos de la especificación %s:

>>> serie='La casa de la pradera'
>>> print('Quién no ha llorado con "%s".' % serie)
Quién no ha llorado con "La casa de la pradera".

Fíjate cómo me las he arreglado para que se impriman las comillas dobles. Al delimitar la cadena en print con comillas simples he podido utilizar las dobles en el interior sin que exista confusión.

Para finalizar voy a plantearte un pequeño problema… Imagina que queremos lograr la siguiente salida:

Puesto que 5 es un entero, la especificación a emplear es %d.

En la que el valor 5 ha sido facilitado por una variable x.

Esto fallaría:

>>> print("Puesto que %d es un entero, la especificación a emplear es %d" % x)
Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    print("Puesto que %d es un entero, la especificación a emplear es %d" % x)
TypeError: not enough arguments for format string

El error es claro: hemos incluido dos especificaciones, pero sólo un argumento. La cuestión es que no queremos que el segundo %d sea interpretado como especificación, sino como un carácter normal.

Para lograr esto utilizaremos un tanto por ciento doble: %%

>>> print("Puesto que %d es un entero, la especificación a emplear es %%d" % x)
Puesto que 5 es un entero, la especificación a emplear es %d

El %% indica que ese % no corresponde a una especificación. El resultado es la impresión de un % simple.

Cuando no usamos el operador de interpolación podemos recurrir al % sin necesidad de usar el doble, pues la construcción no ofrece ambigüedades:

>>> print("%d es la especificación de conversión para enteros y %f para reales")
%d es la especificación de conversión para enteros y %f para reales

Y eso es todo por hoy…

>>> bollo = 'bizcocho'
>>> hora = 8
>>> print("Con esto y un %s, hasta mañana a las %d" % (bollo, hora))
Con esto y un bizcocho, hasta mañana a las 8

Javier Montero Gabarró


Python – Capítulo 34: Especificaciones de conversión


El texto de este artículo se encuentra sometido a una licencia Creative Commons del tipo CC-BY-NC-ND (reconocimiento, no comercial, sin obra derivada, 3.0 unported)


El Club del Autodidacta


Consulta el índice completo de artículos relacionados con Python.

Python – Capítulo 33: Imprimiendo al estilo de C

Tomemos prestada la función desguazar() que diseñamos en el capítulo anterior:

def desguazar(dividendo, divisor):
  cociente = dividendo//divisor
  resto = dividendo%divisor
  return cociente, resto

Vamos a modificarla ligeramente para que, en vez de devolver la tupla con el resto y el divisor nos muestre una frase con el resultado. Esto es, que funcione del siguiente modo:

>>> desguazar(17,5)
El cociente es 3 y el resto es 2.

No parece complicado en absoluto. Una primera aproximación podría ser esta:

def desguazar(dividendo, divisor):
  cociente = dividendo//divisor
  resto = dividendo%divisor
  print("El cociente es", cociente, "y el resto es", resto,".")

Salvo la excesiva distancia del punto final, el resultado es aceptable (recuerda que por defecto print() establece como separador un espacio en blanco).

>>> desguazar(17,5)
El cociente es 3 y el resto es 2 .

Sin embargo, el modo de lograrlo deja bastante que desear: hemos troceado la cadena para poder intercalar los valores enteros, que previamente hemos tenido que convertir en strings.

Si sabes programar en lenguaje C, tal vez sientas algo de añoranza. Con lo bien que resuelve el problema un programador en C con printf

printf("El cociente es %d y el resto es %d.\n", cociente, resto);

¿No existiría algo semejante en Python? ¿No existiría un modo de formatear una cadena de caracteres con especificaciones en su interior?

Desde luego que existe, y no sólo de un modo semejante, sino más flexible aún.

Voy a mostrarte como resolvía Python esto a la antigua usanza. Hoy día, el método format() hace innecesario recurrir a ella, pero puesto que aún sigue siendo perféctamente válida y no parece haber indicios de que vayan a dejarla obsoleta, he preferido explicártela en primer lugar.

Esta es la nueva función. Presta mucha atención a la última sentencia:

 def desguazar(dividendo, divisor):
  cociente = dividendo//divisor
  resto = dividendo%divisor
  print("El cociente es %d y el resto es %d." % (cociente, resto))

Y observa el resultado:

>>> desguazar(17,5)
El cociente es 3 y el resto es 2.

Perfecto.

Fíjate cómo, al igual que en printf, especificamos un valor entero con %d. Puesto que vamos a sustituir dos enteros, %d aparece dos veces en los lugares adecuados dentro de la cadena.

A continuación, una vez hemos cerrado la cadena con las comillas, aparece el símbolo %, que en este contexto es conocido como operador de especificación, formateo o interpolación.

Tras el figura una tupla con las variables que sustituirán cada especificación. Es muy importante que el número de especificaciones en la cadena coincidan con el número de variables en el lado derecho de %. En caso contrario se produciría un error en tiempo de ejecución (una excepción).

Naturalmente, si sólo hubiera una especificación, en lugar de una tupla aparecería un entero simple:

>>> ovejas=17
>>> print("Tengo un rebaño de %d ovejas..." % ovejas)
Tengo un rebaño de 17 ovejas...

Hemos presentado %d, la especificación para enteros con signo en formato decimal (base 10), pero hay otras más para todo tipo de valores. Las iremos presentando gradualmente; entre tanto, asegúrate de comprender la técnica aquí descrita.

Javier Montero Gabarró


Python – Capítulo 33: Imprimiendo al estilo de C


El texto de este artículo se encuentra sometido a una licencia Creative Commons del tipo CC-BY-NC-ND (reconocimiento, no comercial, sin obra derivada, 3.0 unported)


El Club del Autodidacta

Uso de cookies

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.plugin cookies

ACEPTAR
Aviso de cookies