Me gustaría eliminar todos los caracteres de una primera cadena s1 exactamente la cantidad de veces que aparecen en otra cadena s2, es decir, si s1 = "AAABBBCCCCCCD" y s2 = "ABBCCC", el resultado debería ser s = "AABCCCD". (El orden de los caracteres en la cadena resultante en realidad es irrelevante, pero es una ventaja si se puede conservar).
El siguiente código bastante tosco puede hacer esto:
def reduce_string(s1, s2): s = s1 for c in s2: if c in s: s = s.replace(c, "", 1) return(s) # examples reduce_string("AAABBBCCCCCCD", "ABBCCC") reduce_string("AAABBBCCCCCCD", "ABBCCCE")Mi pregunta es, ¿se puede lograr lo mismo mediante el uso inteligente de alguna función integrada o al menos de una manera más elegante? ¡Gracias por todas tus respuestas!
Puedes usar objetos contadores. Resta uno contra el otro y une los elementos restantes.
from collections import Counter s1 = "AAABBBCCCCCCD" s2 = "ABBCCC" counter = Counter(s1) counter.subtract(Counter(s2)) result = ''.join(counter.elements()) print(result) AABCCCDComo una sola línea:
print(''.join((Counter(s1) - Counter(s2)).elements()))Hay una función filterfalse en el módulo itertools que debería ver. Consulta la documentación aquí .
La función filterfalse devuelve elementos de un iterable cuando el predicado se evalúa como False .
Entonces, una posible solución podría ser:
import itertools def reduce_string(s1, s2): def predicate(letter, param=list(s2)): if letter in param: param.remove(letter) return True return False result = itertools.filterfalse(predicate, s1) return ''.join(result) reduce_string("AAABBBCCCCCCD", "ABBCCC") reduce_string("AAABBBCCCCCCD", "ABBCCCE") Sin embargo, observe cómo mi función de predicate es un poco más complicada cuando cambia la segunda cadena.
El argumento de palabra clave param se evalúa cuando el predicate de la función se crea dentro del ámbito reduce_string como un objeto de list .
Dado que la referencia no cambia sino los elementos dentro de param , pude cambiar la segunda cadena por motivos de comparación.
Ahora, la pregunta sigue siendo: ¿existe una forma más elegante de definir la función de predicate ?