Substitution de chaînes de caractères par dictionnaire, en 3 lignes
Aujourd’hui, une petite recette de python que j’ai concoctée pour un besoin très précis. Il s’agit de recevoir une chaîne de caractère, voir si elle contient la chaîne à remplacer en regardant dans un dictionnaire, puis à faire le remplacement. En l’occurence, il s’agit de toujours remplacer le début de la chaîne de caractères.
J’ai donc un dictionnaire de substitution que j’appelle subst_map
qui contient en clé l’élément à retrouver, et en valeur la chaîne de remplacement. Une contrainte supplémentaire est de prendre la correspondance la plus longue, si certaines clés commencent de la même façon.
La méthode la plus évidente est de faire une boucle:
def substitute(input, subst_map): chosen_key = None for k in subst_map.keys(): if input.startswith(k): if chosen_key is None or len(k) > len(chosen_key): chosen_key = k # Le dernier argument de replace() sert à limiter # le nombre de remplacements return input.replace(chosen_key, subst_map[chosen_key], 1)
Et cette méthode fonctionne très bien. Cependant, on peut arriver au même résultat avec très peu de code.
def substitute(input, subst_map): keys = filter(lambda s: input.startswith(s), subst_map.keys()) keys.sort(key=lambda v: len(v), reverse=True) if keys: #si la longueur > 0, j'ai une correspondance # et je prends la première return input.replace(keys[0], subst_map[keys[0]], 1) else: return input
Et c’est tout!
La fonction filter
fait la même chose que ma boucle, mais la condition de filtrage est directement passée comme une fonction anonyme (une lambda). De la même façon, je trie à la volée les clés trouvées par ordre de longueur croissante, pour utiliser la première.
Le code n’est pas forcément plus rapide à l’exécution, mais il est bien plus rapide à écrire, et assez compréhensible. J’aurais même pu faire le filtrage et le tri sur une seule ligne, mais ça aurait été pour le coup plus compliqué à lire.