Contenu du cours
Techniques d'Optimisation en Python
Techniques d'Optimisation en Python
Gestion des Fichiers Volumineux
Traiter efficacement les fichiers volumineux est essentiel lorsque vous travaillez avec des ensembles de données trop grands pour tenir en mémoire. Python fournit des outils comme open()
et map()
, qui vous permettent de traiter les fichiers de manière paresseuse, économisant ainsi de la mémoire et améliorant les performances.
Qu'est-ce qu'un itérateur ?
Avant de procéder avec la fonction open()
, nous devons d'abord comprendre ce qu'est un itérateur. Un itérateur est un objet qui représente un flux de données, vous permettant d'accéder à un élément à la fois. Les itérateurs implémentent deux méthodes :
__iter__()
: retourne l'objet itérateur lui-même ;__next__()
: retourne l'élément suivant dans le flux et lève une exceptionStopIteration
lorsqu'il n'y a plus d'éléments.
Disons que nous avons un itérateur nommé iterator_object
. Nous pouvons itérer dessus en utilisant une boucle for
habituelle :
En fait, en coulisses, ce qui suit se produit (la fonction next()
appelle en interne la méthode __next__()
de l'itérateur) :
Contrairement aux collections standard, les itérateurs se caractérisent par une évaluation paresseuse, ce qui signifie qu'ils génèrent ou récupèrent des données uniquement lorsque cela est nécessaire, plutôt que de tout charger en mémoire d'un coup. Cette approche les rend très efficaces en termes de mémoire, en particulier lors du traitement de grands ensembles de données.
Objets fichiers en tant qu'itérateurs
La fonction open()
retourne un objet fichier, qui est un itérateur. Cela vous permet de :
- Itérer sur un fichier ligne par ligne en utilisant une boucle
for
; - Lire une ligne à la fois en mémoire, ce qui le rend adapté aux fichiers volumineux (tant que les lignes individuelles tiennent en mémoire).
Par exemple, si un fichier journal avec 1,000,000
lignes inclut à la fois des messages INFO
et ERROR
, nous pouvons toujours compter les occurrences de ERROR
en parcourant le fichier ligne par ligne, même si le fichier ne peut pas tenir entièrement en mémoire (ce qui sera le cas si nous ajoutons beaucoup plus de journaux).
log_lines = [f"INFO: Log entry {i}" if i % 100 != 0 else f"ERROR: Critical issue {i}" for i in range(1, 1000001)] with open("large_log.txt", "w") as log_file: log_file.write("\n".join(log_lines)) # Process the file to count error entries error_count = 0 for line in open("large_log.txt"): if "ERROR" in line: error_count += 1 print(f"Total error entries: {error_count}")
Transformer les lignes de fichier avec map()
Comme mentionné dans le chapitre précédent, map()
renvoie un itérateur, appliquant une fonction de transformation de manière paresseuse à chaque ligne d'un fichier. Similaire aux objets fichier, map()
traite les données un élément à la fois sans tout charger en mémoire, ce qui en fait une option efficace pour gérer de grands fichiers.
Par exemple, créons un fichier contenant 1000000
adresses e-mail, dont certaines incluent des lettres majuscules. Notre objectif est de convertir tous les e-mails en minuscules et de sauvegarder les résultats normalisés dans un nouveau fichier ('normalized_emails.txt'
). Nous utiliserons map()
pour y parvenir, en veillant à ce que le script reste efficace et adapté au traitement de fichiers encore plus volumineux.
# Create a file with mixed-case email addresses email_lines = [ "John.Doe@example.com", "Jane.SMITH@domain.org", "BOB.brown@anotherexample.net", "ALICE.williams@sample.com" ] * 250000 # Repeat to simulate a large file with open("email_list.txt", "w") as email_file: email_file.write("\n".join(email_lines)) # Process the file to standardize email addresses (convert to lowercase) with open("email_list.txt") as input_file, open("normalized_emails.txt", "w") as output_file: # Use map() to convert each email to lowercase lowercase_emails = map(str.lower, input_file) for email in lowercase_emails: output_file.write(email) # Print the last email to verify the results print(email) print('Done')
1. Vous devez convertir toutes les adresses e-mail dans un fichier en minuscules et les enregistrer dans un nouveau fichier sans tout charger en mémoire. Quelle approche est la plus efficace ?
2. Laquelle des affirmations suivantes concernant les objets fichier est correcte ?
Merci pour vos commentaires !