Trouver dans fichier texte le premier mot commençant par ...

Résolu
Emzo9 Messages postés 3 Date d'inscription   Statut Membre Dernière intervention   -  
mamiemando Messages postés 33769 Date d'inscription   Statut Modérateur Dernière intervention   -

Bonjour,

Comment trouver, dans un gros fichier texte (environ 3000 mots, un mot par ligne, ordre alphabétique), le 1er mot commençant par une chaîne donnée ? Je le fais avec une boucle FOR, mais est-il possible d'aller plus vite, avec une instruction de recherche directe, un peu comme seek().

A voir également:

4 réponses

PierrotLeFou
 

seek() est utilisé pour se positionner dans un fichier. Où vas-tu te repositionner?
Comment le fais-tu maintenant?
Tu dis "commençant" par une chaîne. Connais-tu le slicing? (si tu connais la longueur de la chaîne?)
Commence par ceci avant de penser à des méthodes plus sophistiquées.
Je le fais facilement avec des fichiers de plus de 300 000 mots.
Ça ne doit pas être si long avec environ 3000 mots.

0
PierrotLeFou
 

repositionner?

Pas moyen de supprimer?


 

0
mamiemando Messages postés 33769 Date d'inscription   Statut Modérateur Dernière intervention   7 878
 

Bonjour,

Un fichier de 3000 mots est petit et donc ta fonction ne nécessite pas spécialement d'optimisation.

De plus, il n'y a pas vraiment d'accélérer le code (ce qui sera "lent", c'est lire le fichier et charger les 3000 mots en mémoire). Donc pour ma part j'écrirais juste ceci.

toto.py

#!/usr/bin/env python3

from pathlib import Path

filename = Path("data.txt")
assert filename.exists()
with open(filename) as f:
    lines = [
        line.strip()
        for line in f.readlines()
        if line.startswith("str")
    ]
print(lines)

data.txt

aaa
bbb
str1
ssstr2
str2aa
str3
xxstr

Exécution :

['str1', 'str2aa', 'str3']

Si tu vises des dictionnaires (vraiment beaucoup) plus grands, tu pourrais envisager de les sérialiser (voir par exemple les modules pickle ou dill).

Ensuite, si la question est comment chercher efficacement l'index d'un élément dans une liste ordonnée (et en mémoire), alors tu pourrais envisager une recherche dichotomique. Voir ici pour plus de détails.

Bonne chance

0
Emzo9 Messages postés 3 Date d'inscription   Statut Membre Dernière intervention  
 

Merci à vous deux.

Voici ce que j'avais fait :

# Trouver ts les mots dans Dico.txt,
# débutant par deb, variable définie en amont.
with open(r"Dico.txt", "r") as f:
    for mot in f:
        if mot[0:len(deb)] == deb:
            # traitement_mot --> appel de la fonction
            # traitant chaque mot concerné

Je vois que tous les deux vous pensez que ça n'a pas besoin d'optimisation. 

Et la méthode avec "startswith" proposée par mamiemando est assez compacte et élégante. Je vais faire ça.

En fait, ce que j'avais en tête, c'est qqchose comme l'instruction FIND, suivie d'une string, qui donnait, autrefois, dans dBase IV, directement l'index du 1er mot débutant par cette string dans le fichier. Sans boucle. Mais bon, je vais m'en tenir au "startswith". Problème résolu.

Un GRAND MERCI à vous deux.

0
mamiemando Messages postés 33769 Date d'inscription   Statut Modérateur Dernière intervention   7 878
 

En fait, c'est surtout que tu ne peux pas faire beaucoup mieux sans passer sur une structure intermédiaire comme un Trie. Générer une telle structure ne devient rentable que si le corpus est très grand (ce qui n'est pas ton cas) et/ou si on fait un très grand nombre de recherches.

0