Résolue

Tri dynamique des fichiers avec générateur

# Fichiers # Python # Générateurs

Je partage (et je suis preneur de retour) une 3ème version pour ce projet. C'est une version "dynamique" dans le sens ou pour modifier les règles de tri, il n'y a qu'à modifier le contenu de la variable mapping.

L'objectif était de faire le moins possible d'imbrication de if / else / boucle en tout genre, tout en gardant quelque chose d'à peu près lisible. En voulant "optimiser" tout ça, je suis tombé sur le principe de générateur qui m'a l'air plutôt bien adapté pour ce TP.

"""
Project : https://www.docstring.fr/formations/le-trieur-de-fichiers/introduction-au-projet-1763/?module=13&session=1&course=1
Description : Sort the content of a directory (non recursively) 
"""

from pathlib import Path

input_directory = Path(r"C:\Users\fva\dev\learning-python-1\data_to_sort")
sorted_directory = Path(r"C:\Users\fva\dev\learning-python-1\sorted_data")
mapping = {
    "Musique": [".mp3", ".wav", ".flac"],
    "Videos": [".avi", ".mp4", ".gif"],
    "Images": [".bmp", ".png", ".jpg"],
    "Documents": [".txt", ".pptx", ".csv", ".xls", ".odp", ".pages"]
}

# create all directories : [...]/data/Musique & Other, etc ....
(sorted_directory / "Other").mkdir(parents=True, exist_ok=True)
for directory in mapping.keys():
    (sorted_directory / directory).mkdir(parents=True, exist_ok=True)

# iterate only over regular file
files = [f for f in input_directory.iterdir() if f.is_file()]
for file in files:

    # if the file extension map a specific category -> put it in the specified category, else, put it in "other" category
    category = next((key for key, value in mapping.items() if file.suffix in value), "Other")
    file.rename(sorted_directory / category / file.name)

Je suis preneur de tout retours / axes d'améliorations.

Salut,

Tu n'as pas de générateur mais une compréhension de liste ici pour charger les fichiers.

Tu pourrais utiliser une expression génératrice :
for file in (f for f in input_directory.iterdir() if f.is_file()):

Elle te permet de traiter les fichiers un par un, sans tout charger en mémoire avant :)

Je suis bien d'accord que la ligne files = [f for f in input_directory.iterdir() if f.is_file()] est une compréhension de liste.

Mais la ligne (key for key, value in mapping.items() if file.suffix in value) c'est bien un générateur non (enfin une expression génératrice) ? Et du coup en le combinant avec next ça me permet de ne pas tout charger en mémoire et d'avoir un retour des que je trouve une correspondance entre une extension de fichier et la liste des extensions dans ma variable mapping.

Gabriel Trouvé

Mentor

Ah excuse moi, j'étais parti sur le filtre pour ne récupérer que les fichiers. Mais oui tu utilises bien une expression génératrice à la fin du script. Du coup même principe que ce que j'ai dit plus haut, c'est super efficace niveau mémoire. C'est vraiment bien de les utiliser.... :)

Inscris-toi

(c'est gratuit !)

Inscris-toi

Tu dois créer un compte pour participer aux discussions.

Créer un compte

Rechercher sur le site

Formulaire de contact

Inscris-toi à Docstring

Pour commencer ton apprentissage.

Tu as déjà un compte ? Connecte-toi.