Python: Rechercher tous les anagrammes dans un texte

Selon wikipédia, une anagramme est un mot ou une expression obtenu en permutant les lettres d'un mot ou d'une expression de départ.

Pour l'exemple, je vais rechercher tous les anagrammes présents dans l'oeuvre de Jules Verne, "Le Tour Du Monde En 80 Jours".

Première étape, récupérer l'oeuvre au format txt.
Le site gutenberg permet de faire ce genre de choses.

Le module requests permet d'exécuter des requêtes HTTP

$ python3 -m pip install --upgrade requests
>>> import requests
>>> r1 = requests.get('https://www.gutenberg.org/files/800/800-8.txt')

Récupération du texte dans la réponse de la requête et nettoyage de tous les caractères non indispensables.
Le texte commence au 3 941 ème caractères et se termine au 431 252 ème caractères.
Tous les accents sont supprimés.
Tout le texte est converti en minuscule.
La regex recherche tous les mots de 3 caractères et plus.
Tous les mots en double sont supprimés.

Pour la suppression des caractères accentués, j'utilise le module removeaccents

$ python3 -m pip install --upgrade removeaccents
>>> from removeaccents.removeaccents import remove_accents
>>> text = r1.text[3941:431252]
>>> text = remove_accents(text)
>>> text = text.lower()
>>> words = re.findall(r'\b[A-Za-z]{3,}\b', text)
>>> words = list(set(words))

Nous nous retrouvons avec une liste de 8426 mots de 3 caractères et plus.

>>> len(words)
8426

Nous allons maintenant indexer tous les anagrammes dans un dictionnaire.

>>> anagrammes = dict()
>>> for word in words:
    letters = ''.join(sorted(word))
    if letters in anagrammes:
        anagrammes.get(letters).append(word)
    else:
        anagrammes[letters] = [word]
>>> anagrammes = {k: v for k, v in anagrammes.items() if len(v) > 1}

Nous obtenons une liste de 312 anagrammes

>>> len(anagrammes)
312

Voici la liste des 30 premiers anagrammes triée par ordre décroissant du nombre de mots.

>>> print(sorted(anagrammes.items(), key=lambda x: len(x[1]), reverse=True)[:30])
[('aerstu', ['sauter', 'autres', 'surate']), ('eeprst', ['pertes', 'pester', 'pretes']), ('eeelrv', ['releve', 'revele', 'elever']), ('aeenprst', ['esperant', 'presenta', 'separent']), ('aeiprt', ['partie', 'pirate', 'patrie']), ('efmnort', ['froment', 'forment', 'fremont']), ('aisv', ['vais', 'avis', 'visa']), ('aceinrt', ['crainte', 'ecriant', 'certain']), ('aceerss', ['sacrees', 'caresse', 'cessera']), ('aerrs', ['rares', 'raser', 'serra']), ('aeirstt', ['artiste, 'restait', 'attires']), ('eimprs', ['permis', 'mepris', 'primes']), ('eegnr', ['green', 'genre', 'gener']), ('adegr', ['garde', 'egard', 'grade']), ('eirsv', ['servi', 'viser', 'rives']), ('aeegilns', ['inegales', 'alignees', 'signalee']), ('aegnt', ['agent', 'geant', 'etang']), ('acert', ['ecart', 'trace', 'carte']), ('eeinrtt', ['interet', 'retenti', 'retient']), ('adegnrs', ['grandes', 'dangers', 'gardens']), ('eerrsv', ['verres', 'revers', 'verser']), ('aeirrtt', ['traiter', 'attirer', 'traitre']), ('acers', ['sacre', 'races', 'arecs']), ('ersu', ['user', 'rues', 'ruse']), ('cdeirt', ['decrit', 'credit', 'direct']), ('einru', ['nuire', 'ruine', 'reuni']), ('bceimno', ['combien', 'combine']), ('eirtv', ['vitre', 'revit']), ('aceimnoprt', ['importance', 'comprenait']), ('aceinrst', ['certains', 'craintes'])]

 

Ajouter un commentaire

Filtered HTML

  • Les adresses de pages web et de messagerie électronique sont transformées en liens automatiquement.
  • Tags HTML autorisés : <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Les lignes et les paragraphes vont à la ligne automatiquement.

Plain text

  • Aucune balise HTML autorisée.
  • Les adresses de pages web et de messagerie électronique sont transformées en liens automatiquement.
  • Les lignes et les paragraphes vont à la ligne automatiquement.
CAPTCHA
Cette question permet de s'assurer que vous êtes un utilisateur humain et non un logiciel automatisé de pollupostage.
CAPTCHA visuel
Entrez les caractères (sans espace) affichés dans l'image.