Estoy tratando de hacer un script simple que reemplace todas las apariciones de cierto grupo o conjunto de caracteres (o conjunto de cadenas) en el texto.
En este caso, intentaré reemplazar todas las letras "a, e, i, o, u" con cierta cadena.
Mi guión:
def replace_all(text, repl):
text1 = text.replace("a", repl)
text2 = text1.replace("e", repl)
text3 = text2.replace("i", repl)
text4 = text3.replace("o", repl)
text5 = text4.replace("u", repl)
return text5
¿Hay alguna forma más sencilla de hacerlo? ¿Qué sucede si necesito reemplazar un grupo más grande de caracteres o cadenas? Encadenarlo así no parece ser realmente efectivo entonces.
Esta es quizás una pregunta primitiva. Sin embargo, todavía estoy en la fase de aprendizaje, así que tal vez lo obtenga en lecciones posteriores. Gracias de antemano por cualquier consejo.
3 respuestas
Mi conocimiento me dice que hay 3
diferentes formas de hacer esto, todas las cuales son más cortas que su método:
- Usando un
for-loop
- Usando un
generator-comprehension
- Usando
regular expressions
Primero, usando un for-loop
. Esta es probablemente la mejoría más directa para su código y esencialmente solo reduce las líneas 5
con .replace
hasta 2
:
def replace_all(text, repl):
for c in "aeiou":
text = text.replace(c, repl)
return text
También puede hacerlo en una línea utilizando un generator-comprehension
, combinado con el método str.join
. Esto sería más rápido (si eso es importante) ya que es de complejidad O(n)
ya que revisaremos cada carácter y lo evaluaremos una vez (el primer método es la complejidad O(n^5)
ya que Python realizará un bucle hasta text
cinco veces para los diferentes reemplazos) .
Entonces, este método es simplemente:
def replace_all(text, repl):
return ''.join(repl if c in 'aeiou' else c for c in text)
Finalmente, podemos usar re.sub
para sustituir Todos los caracteres del conjunto: [aeiou]
con el texto repl
. Esta es la solución más corta y probablemente lo que recomendaría:
import re
def replace_all(text, repl):
return re.sub('[aeiou]', repl, text)
Como dije al principio, todos estos métodos completan la tarea, por lo que no tiene sentido proporcionar casos de prueba individuales, pero funcionan como se ve en esta prueba:
>>> replace_all('hello world', 'x')
'hxllx wxrld'
Actualizar
Me ha llamado la atención un nuevo método: str.translate
.
>>> {c:'x' for c in 'aeiou'}
{'a': 'x', 'e': 'x', 'i': 'x', 'o': 'x', 'u': 'x'}
>>> 'hello world'.translate({ord(c):'x' for c in 'aeiou'})
'hxllx wxrld'
Este método también es O(n)
, por lo que es tan eficiente como los dos anteriores.
Entonces, lo que estás haciendo es perfectamente válido, sin embargo, hay mejores formas.
Aquí hay algunas soluciones, con tiempos de ejecución tomados sobre 100000 bucles.
La firma principal:
Los objetivos son los caracteres que desea reemplazar, repl es el carácter de reemplazo.
def replace_all(text, targets=['a', 'e', 'i', 'o', 'u'], repl='_'):
text = # Something here to swap characters as an array
return ''.join(text) # Stitch it back together
Bytearray
Bytearray es una estructura de datos mutable que contiene una lista de los propios caracteres . Como estructura de datos, aparentemente es la opción ideal, las cadenas en python son inmutables, esto funciona para evitar la construcción / destrucción constante.
[chr(c) if chr(c) not in targets else repl for c in bytearray(text, 'utf-8')]
Se ejecuta en 0.365
Sin bytearray
Esto opera en una lista simple, la lista en sí es mutable, pero los caracteres son cadenas, por lo tanto aquí hay alguna modificación de estructuras técnicamente inmutables.
[c if c not in targets else repl for c in text]
Corre en 0.179
Mapa
Esto asigna la función a cada carácter en la cadena.
map(lambda c: c if c not in targets else repl, text)
Se ejecuta en 0.265
Este es un buen lugar para una expresión regular:
import re
def replace_all(text, repl):
return re.sub('[aeiou]', repl, text)
Esto funcionará para el caso en su pregunta, donde está reemplazando caracteres individuales. Si desea reemplazar un conjunto de cadenas más largas:
def replace_all(text, to_replace, replacement):
pattern = '|'.join(to_replace)
return re.sub(pattern, replacement, text)
>>> replace_all('this is a thing', ['thi','a'], 'x')
'xs is x xng'
Preguntas relacionadas
Preguntas vinculadas
Nuevas preguntas
python
Python es un lenguaje de programación multipropósito, de tipificación dinámica y de múltiples paradigmas. Está diseñado para ser rápido de aprender, comprender y usar, y hacer cumplir una sintaxis limpia y uniforme. Tenga en cuenta que Python 2 está oficialmente fuera de soporte a partir del 01-01-2020. Aún así, para preguntas de Python específicas de la versión, agregue la etiqueta [python-2.7] o [python-3.x]. Cuando utilice una variante de Python (por ejemplo, Jython, PyPy) o una biblioteca (por ejemplo, Pandas y NumPy), inclúyala en las etiquetas.