El ejemplo específico que da (borrar caracteres individuales) es perfecto para el método translate
de cadenas, como lo es la sustitución de caracteres individuales con caracteres únicos. Si la cadena de entrada es una de Unicode, entonces, además de los dos tipos anteriores de "sustitución", la sustitución de caracteres individuales con cadenas de caracteres múltiples también está bien con el método translate
(aunque si necesita trabajar con cadenas de bytes))
Si necesita reemplazar subcadenas de múltiples caracteres, entonces yo también recomendaría el uso de una expresión regular - aunque no en la forma en que la respuesta de @ gnibbler recomienda; más bien, construiría la expresión regular desde r'onestring|another|yetanother|orthis'
(unir las subcadenas que deseas reemplazar con barras verticales - asegúrate también de incluirlas en re.escape
si contienen caracteres especiales, por supuesto) y escribir una función de sustitución simple basada en un dict.
No voy a ofrecer mucho código en este momento ya que no sé cuál de los dos párrafos se aplica a sus necesidades reales, pero (cuando más tarde regrese a casa y verifique SO nuevamente ;-) Estaré encantado de editar para agregar un ejemplo de código según sea necesario dependiendo de sus modificaciones a su pregunta (más útil que los comentarios a esta respuesta ;-).
Editar: en un comentario el PO dice que quiere una respuesta "más general" (sin aclarar lo que eso significa) a continuación, en una edición de su Q dice que quiere estudiar las "compensaciones" entre diversos fragmentos todos de los cuales usan subcadenas de un solo carácter (y comprueban su presencia, en lugar de reemplazar como se solicitó originalmente, una semántica completamente diferente, por supuesto).
Dada esta total y completa confusión, todo lo que puedo decir es que para "controlar las compensaciones" (rendimiento) me gusta usar python -mtimeit -s'setup things here' 'statements to check'
(asegurándome de que las afirmaciones para verificar no tienen efectos secundarios para evitar distorsiones en las mediciones de tiempo, timeit
realiza bucles implícitamente para proporcionar mediciones precisas de tiempo).
una respuesta general (sin ningún tipo de ventajas y desventajas, y la participación de subseries de varios caracteres, de modo completamente contrario a su edición de Q pero consonantes a sus comentarios - los dos es totalmente contradictorio que es, por supuesto, imposible de cumplir ambos):
import re
class Replacer(object):
def __init__(self, **replacements):
self.replacements = replacements
self.locator = re.compile('|'.join(re.escape(s) for s in replacements))
def _doreplace(self, mo):
return self.replacements[mo.group()]
def replace(self, s):
return self.locator.sub(self._doreplace, s)
ejemplo uso:
r = Replacer(zap='zop', zip='zup')
print r.replace('allazapollezipzapzippopzip')
Si algunas de las subcadenas que ser reemplazadas son palabras clave de Python, que necesitan para ser aprobada en un poco menos directamente, por ejemplo,, Lo siguiente:
r = Replacer(abc='xyz', def='yyt', ghi='zzq')
fallarían porque def
es una palabra clave, por lo que necesita ej .:
r = Replacer(abc='xyz', ghi='zzq', **{'def': 'yyt'})
o similares.
Me parece un buen uso para una clase (en lugar de programación de procedimiento) porque el RE para localizar las subcadenas a reemplazar, el dict expresando con qué reemplazarlas, y el método que realiza el reemplazo, realmente claman ser "mantenidos todos juntos", y una instancia de clase es la forma correcta de realizar dicho "mantenimiento conjunto" en Python. Una fábrica de cierre también podría funcionar (ya que el método replace
es realmente la única parte de la instancia que necesidades sean visibles "fuera"), pero en una posiblemente menos clara, más difícil de depurar manera:
def make_replacer(**replacements):
locator = re.compile('|'.join(re.escape(s) for s in replacements))
def _doreplace(mo):
return replacements[mo.group()]
def replace(s):
return locator.sub(_doreplace, s)
return replace
r = make_replacer(zap='zop', zip='zup')
print r('allazapollezipzapzippopzip')
La única ventaja real podría ser un rendimiento modestamente mejor (debe verificarse con timeit
en "casos de referencia" considerados significativos y representativos para la aplicación que lo usa) como el acceso a las "variables libres" (replacements
, locator
, _doreplace
) en este caso podría ser minuciosamente más rápido que el acceso a los nombres calificados (self.replacements
, etc.) en el enfoque normal basado en la clase (si esto es el caso dependerá de la implementación de Python en uso, de ahí la necesidad de verificar con timeit
en puntos de referencia significativos!).
No estoy seguro de cómo piensa utilizar una tabla de búsqueda: ¿cuáles son las claves y los valores? Además, su ejemplo tiene algunos errores tipográficos/incoherencias. – zdav
¿Dónde están los errores tipográficos? He usado puntos suspensivos para truncar el ejemplo de legibilidad. –