Saltar al contenido

Cómo eliminar las vocales de una cadena de texto en Python

como-eliminar-las-vocales-de-una-cadena-de-texto-en-python

No dejes que el título de este artículo te engañe.

Puede parecer un ejercicio simple, casi para principiantes.

Y puede serlo, pero también puede ser una masterclass alucinante sobre Python. Y eso es lo que pretendo con este artículo.

Sigue leyendo y lo comprobarás.

Se trataba de hacer una función de Python que reciba una cadena de texto y devuelva otra, que es la de entrada pero sin las vocales.

Por ejemplo, para la entrada 'Bob Esponja', debe devolver 'Bb spnj'. (¿Quién vive en la piña debajo del mar?)

Pues vamos allá.

Solución tradicional

Primero, una solución “tradicional” que funciona y es relativamente fácil de leer y de entender.

def eliminar_vocales(cadena):
    resultado = ''
    vocales = 'aeiouAEIOU'
    for c in cadena:
        if c not in "aeiou":
            resultado += c
    return resultado

Simplemente vamos recorriendo la cadena. Si encontramos una consonante la añadimos al resultado final.

Fíjate que para comprobar si una letra es una vocal usamos el operador in con una cadena que contiene las vocales en minúsculas o en mayúsculas 'aeiouAEIUO'. Esto devolverá False (por usar not in) si la letra es una vocal.

¿Por qué no me gusta esta solución?

Precisamente por ser demasiado tradicional. Python es un lenguaje moderno y de alto nivel y, normalmente, podemos huir de este tipo de soluciones.

Además, en cada vuelta del bucle, y cada vez que encontramos una consonante, se crea una nueva cadena de texto al usar el operador +. Hay que recordar que las cadenas de texto en Python son no mutables, es decir, no podemos modificarlas, de forma que hay que crear una nueva cada vez que queramos cambiar una.

Veamos otra solución similar pero un poco más pitónica.

Solución tradicional mejorada

def eliminar_vocales(cadena):
    vocales = 'aeiouAEIOU'
    for vocal in vocales:
        cadena = cadena.replace(vocal, '')
    return cadena

Es un poco mejor porque hacemos uso de una de las funciones de las cadenas, que es replace, para eliminar caracteres. Aquí, lo que hago es sustituir cada vocal por la cadena vacía '', de forma que el resultado es una eliminación.

Pero tampoco me gusta y es poco eficiente por dos motivos.

A ver, te cuento...

Te envío todos los días un consejo para que cada día seas mejor en Python.
Puede ser un truco, una píldora, un tip, una historia de mentalidad o motivación, cualquier cosa...
Siempre sobre Python y programación.
Más de 2500 personas como tú los reciben cada día.

Día que estás fuera, consejo sobre Python que te pierdes.
Abajo te suscribes a la lista de correo y te regalo un montón de cosas: La Hoja de Referencia de Python, el Tutorial Interactivo, 30 Ejercicios de Python y la Guía de ChatGPT y Python. By the face.

✅ Contenido exclusivo de alto valor      ✅ Sin spam      ✅ Cancela cuando quieras



Antes de suscribirte consulta aquí la 
Información Básica sobre Protección de Datos. Responsable de datos: Juan Monroy Camafreita.
Finalidad de recogida y tratamiento de datos personales: enviarte boletín informativo de Python y comunicaciones comerciales.
Legitimación: tu consentimiento.
Destinatarios: no se ceden a terceros. Los datos se almacenan en los servidores de marketing (GetResponse).
Derechos: podrás ejercer tus derechos de acceso, rectificación, limitación y supresión de datos en info @ codigopiton.com así como presentar una reclamación ante una autoridad de control.
Más información: política de privacidad, encontrarás información adicional sobre la recopilación y el uso de tu información personal.

En el bucle, recorremos la cadena una y otra vez (que podría ser muy larga) para eliminar la vocales (esto lo hace replace). Y no solo eso, si no que se crea una nueva cadena tras la eliminación de cada vocal. También podemos (y debemos) huir de eso.

Vale, movámonos hacia una solución más pitonesca, más pitónica, más pitoniana…

Eliminando vocales usando comprensiones de listas

Usemos comprensiones… y join.

def eliminar_vocales(cadena):
    vocales = 'aeiouAEIOU'
    return ''.join([c for c in cadena if c not in vocales])

Mejor, ¿no?

Esto me va gustando más. Creo que a ti también.

Creamos una lista a partir de las letras que no son vocales y finalmente convertimos la lista a una cadena con join (que une distintas cadenas de texto usando otra cadena como conector, en este caso, la cadena vacía).

Pero no acaba aquí la cosa, sigamos viendo opciones y mejoras.

Mejoras varias

Hay algo en esa última solución que me chirría. Y es considerar de esa manera las vocales minúsculas y las mayúsculas.

Trabajemos solo con las minúsculas y hagamos una transformación a cada letra de la cadena para hacer la comparación apoyándonos en la función lower. Quedaría así:

def eliminar_vocales(cadena):
    vocales = 'aeiou'
    return ''.join(c for c in cadena if c.lower() not in vocales)

De esta manera, el código es más eficiente al comprobar si cada letra es una vocal (solo buscamos en una cadena de 5 caracteres y no de 10), pero en cambio, hay que hacer una transformación en cada letra. ¿Habremos ganado mucho? (Te dejo pensarlo a ti).

Además, fíjate que esta vez, en lugar de hacer la comprensión de listas para generar una lista, usamos una expresión generadora, consiguiendo el mismo efecto sin poner los corchetes [ y ].

Podemos mejorar, de todas formas, esa última comprobación haciendo que, en lugar de buscar en una cadena de texto se busque en un conjunto, que es mucho más rápido.

Lo cambiamos por:

def eliminar_vocales(cadena):
    vocales = set('aeiou')
    return ''.join(c for c in cadena if c.lower() not in vocales)

Eso sí, ahora que tenemos una forma mucho más rápida de comprobar si una letra es una vocal.

De todas formas,creo que, aunque sea más feo, sería mejor volver a considerar minúsculas y mayúsculas sin hacer la transformación para ganar algo de velocidad (pues la operación de búsqueda en el conjunto sigue siendo igual de rápida).

def eliminar_vocales(cadena):
    vocales = set('aeiouAEIOU')
    return ''.join(c for c in cadena if c not in vocales)

Sí, ya sé que parece que te estoy mareando, pero quiero que me acompañes en todo el razonamiento para que no te quede ninguna duda.

Vale, hasta ahora, hemos hecho algunas mejoras de eficiencia. Vamos a ver otras opciones de implementación.

Con programación funcional y filter

Si eres más de programación funcional que de comprensiones, podrías pensar en la siguiente solución:

15 conceptos fundamentales que necesitas conocer para aprender y dominar Python

Te voy a hacer cuatro regalos (no uno, no dos, no tres, cuatro) que hablan de estos 15 conceptos fundamentales de Python: mi Tutorial Básico Interactivo de Python, una cheat sheet de Python en español: La Hoja de Referencia de Python, una guía de ChatGPT y Python y 30 ejercicios de Python (es un reto para ti).

Estos regalos son exclusivos para los suscriptores de Código Pitón.

👍 Quiero mis cuatro regalos

def eliminar_vocales(cadena):
    vocales = set('aeiouAEIOU')
    return ''.join(filter(lambda c: c not in vocales, cadena))

También me gusta. (Te dejo una pregunta.., ¿cuál será más eficiente, esta solución o la anterior? Haz tus pruebas…).

Claro que entramos en terrenos un poco más avanzados. Lo que hace filter es filtrar aquellos caracteres de la cadena de texto que no cumplen la condición indicada en la función lambda y dejar los que sí la cumplen.

Por cierto, filter no devuelve una lista, así que debemos convertirlo con el constructor list.

Con expresiones regulares

Veamos otra solución radicalmente diferente usando expresiones regulares. Sí, ya sé que asustan, pero es otra opción corta y concisa (y clara si entiendes las expresiones regulares, que, en este caso, la que se usa es muy sencilla):

import re

def eliminar_vocales(cadena):
    return re.sub(r'[aeiouAEIOU]', '', cadena)

¿Cómo vas?

¿Te das cuenta de todo el petróleo que podemos sacar de un ejercicio que es muy sencillo en apariencia?

Pues venga, que estoy on fire, sigamos aprendiendo. Vamos con unas soluciones un poco más creativas. No necesariamente mejores o más eficientes o más legibles, simplemente diferentes, para aprender otros modos.

En definitiva, para aprender más…

Diccionarios de traducción para cadenas de texto: maketrans y translate

Usemos diccionarios de traducción:

def eliminar_vocales(cadena):
    vocales = 'aeiouAEIOU'
    traduccion = str.maketrans('', '', vocales)
    return cadena.translate(traduccion)

A ver, que ya ni te explico el código de arriba. Investiga un poco...

Con programación funcional y reduce

Sigamos por la vía funcional y utilicemos reduce:

from functools import reduce

def eliminar_vocales(cadena):
    vocales = set('aeiouAEIOU')
    return reduce(lambda r, c: r + c if c not in vocales else r, cadena, '')

¿Qué? ¿Cómo lo llevas?

Venga, una más y acabamos con la paliza. Prometido.

Mejoremos la solución tradicional: deque

Iremos a la solución tradicional de vuelta pero utilizaremos deque (otra estructura de datos interesante y que hay que conocer) para incrementar la eficiencia. el truco aquí está en que la operación append de deque es mucha más eficiente que el append de una lista.

def eliminar_vocales(cadena):
    vocales = set('aeiouAEIOU')
    resultado = deque()
    for c in cadena:
        if c not in vocales:
            resultado.append(c)
    return ''.join(resultado)

Y, ya basta, ¡Juan, por dios, para ya!

Que sí, que sí, que ya paro…

Conclusiones

Bueno, espero que veas lo que se puede ocultar realmente detrás de un ejercicio sencillo en apariencia.

Hay mucha miga en este artículo y mucho que aprender, así que guárdalo en favoritos.

Recibe contenido exclusivo de Python y programación y obtén gratis mi reto para ti: 30 Ejercicios de Python.
Todos los días te envío un consejo sobre trucos de Python, ejercicios, secretos, mentalidad, sintaxis, historias de motivación, etc.
Día que estás fuera, consejo sobre Python que te pierdes.
✅ Contenido de alto valor      ✅ Sin spam      ✅ Cancela cuando quieras


Antes de suscribirte consulta aquí la 
Información Básica sobre Protección de Datos. Responsable de datos: Juan Monroy Camafreita.
Finalidad de recogida y tratamiento de datos personales: enviarte boletín informativo de Python y comunicaciones comerciales.
Legitimación: tu consentimiento.
Destinatarios: no se ceden a terceros. Los datos se almacenan en los servidores de marketing (GetResponse).
Derechos: podrás ejercer tus derechos de acceso, rectificación, limitación y supresión de datos en info @ codigopiton.com así como presentar una reclamación ante una autoridad de control.
Más información: política de privacidad, encontrarás información adicional sobre la recopilación y el uso de tu información personal.

Espero que alguna de las soluciones de arriba sea lo que estabas buscando y, por otro lado, espero que hayas podido aprender mucho.

Por cierto, dos cosas.

  1. Si te gusta esta manera de aprender, realizando los ejercicios de varias maneras, tengo un plan de mejora de Python que es perfecto para ti. Se llama El Gimnasio de Python y en él practicarás un único ejercicio a la semana. Infórmate aquí sobre El Gimnasio de Python.
  2. Tengo una newsletter gratuita en la que escribo un correo con un consejo de Python al día. Este artículo que ves es el contenido de uno de los correos que envío. Para que veas lo que te puede llegar a tu bandeja de entrada. Aquí te apuntas a la newsletter de Código Pitón.

Y nada más, espero que todo esto te sea muy útil.

Si te ha gustado lo que has leído, ESTO TE VA A ENCANTAR...

Te envío todos los días un consejo para que cada día seas mejor en Python.
Puede ser un truco, una píldora, un tip, una historia de mentalidad o motivación, cualquier cosa...
Siempre sobre Python y programación.
Más de 2500 personas como tú los reciben cada día.

Día que estás fuera, consejo sobre Python que te pierdes.
Abajo te suscribes a la lista de correo y te regalo un montón de cosas: La Hoja de Referencia de Python, el Tutorial Interactivo, 30 Ejercicios de Python y la Guía de ChatGPT y Python. By the face.

✅ Contenido exclusivo de alto valor      ✅ Sin spam      ✅ Cancela cuando quieras



Antes de suscribirte consulta aquí la 
Información Básica sobre Protección de Datos. Responsable de datos: Juan Monroy Camafreita.
Finalidad de recogida y tratamiento de datos personales: enviarte boletín informativo de Python y comunicaciones comerciales.
Legitimación: tu consentimiento.
Destinatarios: no se ceden a terceros. Los datos se almacenan en los servidores de marketing (GetResponse).
Derechos: podrás ejercer tus derechos de acceso, rectificación, limitación y supresión de datos en info @ codigopiton.com así como presentar una reclamación ante una autoridad de control.
Más información: política de privacidad, encontrarás información adicional sobre la recopilación y el uso de tu información personal.
30 ejercicios de Python

Mira, te envío 30 ejercicios de Python para practicar todo el Python que necesitas saber para programar con soltura.

Son variados y de distintas dificultades. Tendrás un poco de todo: variables, condicionales, funciones, ficheros, listas, diccionarios, etc.

Y de regalo: La Hoja de Referencia de Python. Pon tu email aquí abajo ahora y te los envío.

Información Básica de Protección de Datos. Responsable de datos: Juan Monroy Camafreita.
Finalidad de recogida y tratamiento de datos personales: enviarte boletín informativo de Python y ofertas de productos y servicios propios.
Legitimación: tu consentimiento.
Destinatarios: no se ceden a terceros. Los datos se almacenan en los servidores de marketing (GetResponse).
Derechos: podrás ejercer tus derechos de acceso, rectificación, limitación y supresión de datos en info @ codigopiton.com así como presentar una reclamación ante una autoridad de control.
Más información: política de privacidad, encontrarás información adicional sobre la recopilación y el uso de tu información personal.