php tiene la función strtr
:de php para el pitón
strtr('aa-bb-cc', array('aa' => 'bbz', 'bb' => 'x', 'cc' => 'y'));
# bbz-x-y
Sustituye claves de diccionario en una cadena con los valores correspondientes y (importante) no reemplaza ya reemplazado cuerdas. Un intento ingenuo para escribir la misma en Python:
def strtr(strng, replace):
for s, r in replace.items():
strng = strng.replace(s, r)
return strng
strtr('aa-bb-cc', {'aa': 'bbz', 'bb': 'x', 'cc': 'y'})
vuelve xz-x-y
que no queremos es (bb
obtuve reemplazado de nuevo). ¿Cómo cambiar la función anterior para que se comporte como su contraparte php?
(Preferiría una respuesta sin expresiones regulares, si es posible).
Upd: algunas buenas respuestas aquí. Me ellos cronometrados y se encontró que para las cadenas cortas versión de Gumbo parece ser el más rápido, en cadenas más largas el ganador es la solución re
:
# 'aa-bb-cc'
0.0258 strtr_thg
0.0274 strtr_gumbo
0.0447 strtr_kojiro
0.0701 strtr_aix
# 'aa-bb-cc'*10
0.1474 strtr_aix
0.2261 strtr_thg
0.2366 strtr_gumbo
0.3226 strtr_kojiro
Mi propia versión (que está ligeramente optimizado Gumbo):
def strtr(strng, replace):
buf, i = [], 0
while i < len(strng):
for s, r in replace.items():
if strng[i:len(s)+i] == s:
buf.append(r)
i += len(s)
break
else:
buf.append(strng[i])
i += 1
return ''.join(buf)
códigos y tiempos completos: https://gist.github.com/2889181
Ambos nos falta esto (del documento strtr): primero se probarán las claves más largas. –
Gracias, esto funciona bien (excepto por el error tipográfico). – georg