Plus rapide Python méthode pour rechercher et remplacer sur une grande chaîne
Je suis à la recherche de la façon la plus rapide de remplacer un grand nombre de sous-chaînes de caractères à l'intérieur d'une très grande chaîne. Voici deux exemples que j'ai utilisés.
findall() se sent plus simple et plus élégante, mais elle prend une étonnante quantité de temps.
finditer() enflamme un gros fichier, mais je ne suis pas sûr que ce soit la bonne façon de le faire.
Voici un exemple de code. Notez que le texte actuel je suis intéressé par une chaîne unique autour de 10 MO en taille, et il y a une énorme différence entre ces deux méthodes.
import re
def findall_replace(text, reg, rep):
for match in reg.findall(text):
output = text.replace(match, rep)
return output
def finditer_replace(text, reg, rep):
cursor_pos = 0
output = ''
for match in reg.finditer(text):
output += "".join([text[cursor_pos:match.start(1)], rep])
cursor_pos = match.end(1)
output += "".join([text[cursor_pos:]])
return output
reg = re.compile(r'(dog)')
rep = 'cat'
text = 'dog cat dog cat dog cat'
finditer_replace(text, reg, rep)
findall_replace(text, reg, rep)
Mise à JOUR Ajouté re.sous méthode d'essais:
def sub_replace(reg, rep, text):
output = re.sub(reg, rep, text)
return output
Résultats
re.sub() - 0:00:00.031000
finditer() - 0:00:00.109000
findall() - 0:01:17.260000
pourquoi n'êtes-vous pas à l'aide de re sous méthode?
À l'aide de += avec des cordes est un O(n^2), par rapport à l'O(n), de la construction d'une liste et à l'aide de "" à la rejoindre.
Sören: oui, la différence entre les deux méthodes est profonde.
C'est un exemple très simplifié? Parce que vous pouvez simplement utiliser
the_string.replace('dog', 'cat')
. Si elle l'est, comment compliqué, c'est de la réelle regex?OriginalL'auteur cyrus | 2011-02-04
Vous devez vous connecter pour publier un commentaire.
La méthode standard consiste à utiliser le haut -
D'ailleurs la raison de la différence de performances entre les versions est que chaque remplacement de votre première version des causes de la totalité de la chaîne à être recopié. Les Copies sont rapides, mais quand vous copiez des 10 MO à un aller, un nombre suffisant de copies ralentira.
OriginalL'auteur btilly
Vous le pouvez, et je pense que vous devez parce que c'est certainement une fonction optimisée, l'utilisation
La raison pour laquelle votre findall_replace() fonction est long, c'est qu'à chaque match, une nouvelle chaîne de création de l'objet, comme vous le verrez par exécutée le code suivant:
Noter que dans ce code, je l'ai remplacé
output = text.replace(match, rep)
avectext = text.replace(match, rep)
, sinon seule la dernière occurence est remplacé.finditer_replace() est longue pour la même raison que pour findall_replace(): la répétition de la création d'un objet de type string. Mais le premier utilise un itérateur re.finditer() tandis que le dernier construit préalablement une liste d'objet, de sorte qu'il est plus long. C'est la différence entre itérateur et pas itérateur.
OriginalL'auteur eyquem
Par le moyen de votre code avec findall_replace() n'est pas sûr, il peut retourner unawaited résultats:
affichage
OriginalL'auteur eyquem