IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

demande d'aide en python


Sujet :

Python

  1. #1
    Futur Membre du Club
    Inscrit en
    Février 2011
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 4
    Points : 7
    Points
    7
    Par défaut demande d'aide en python
    Bonjour à tous!
    aidez moi svp!

    Il s'agira de creer un programme recursif qui traversera un repertoire de manière recursive et affichera seulement les fichiers .txt et .jpg
    l'affichage se fera de la manière suivante:

    A
    ___a.jpg
    ___b.txt

    __B
    __c.txt
    C
    __c.jpg
    __d.txt

    merci pour votre aide!

  2. #2
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Salut,

    Pas besoin de créer un programme pour cela, c'est inclus dans Python.

    http://docs.python.org/2/library/os.html#os.walk

    Il ne reste qu'à filtrer les types de fichiers.

  3. #3
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    En fait tout est dans la faq:
    Pour lister un répertoire c'est ici et pour connaître l'extension d'un fichier ici (os.path.splitext(files)[1].lower() in ('.txt', '.jpg') par exemple).

    os.walk (voir l'exemple de la faq plus haut) retournant root, dirs, files cela correspond plus a votre demande : root c'est vos répertoires (A, etc...) et files la liste des fichiers que vous devez traiter.

    Au passage jetez aussi un œil à os.path (et, accessoirement os pour les droits, os.listdir, os.walk, etc...)

    Si vous voulez vraiment vous lancer dans la récursion vous avez os.listdir pour lister un répertoire: A vous de faire le tri avec os.path.isfile(path)/os.path.isdir(path) et de réutiliser la fonction si os.path.isdir(path).
    Mais bon... Comme le dit VinsS cela existe déjà.

    @+
    Merci d'utiliser le forum pour les questions techniques.

  4. #4
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 471
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 471
    Points : 9 265
    Points
    9 265
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Il est vrai qu'il est difficile de faire plus simple que les exemples de la faq.

    En ce qui me concerne, je préfère en général coder plus fin que walk (au risque de fabriquer des bugs...), pour mieux m'adapter au résultat voulu.

    Voilà un exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    from __future__ import division
    # Python 2.7
     
    import os
     
    from fnmatch import fnmatch
     
    #############################################################################
    def listefichiers(repertoire, selections=['*'], niveau=0):
        """affiche les répertoires et les fichiers conformes aux sélections"""    
     
        # lecture des noms du répertoire
        try:
            noms = os.listdir(repertoire)
        except Exception:
            print
            print u"Impossible de rentrer dans le répertoire ", repertoire
            return
     
        # enregistrement des sous-répertoires et des fichiers sélectionnés
        reperts, fichiers = [], [] 
        for nom in noms:
            if os.path.isdir(os.path.join(repertoire, nom)):
                # enregistrement du répertoire trouvé
                reperts.append(nom) 
            else:
                # enregistrement du fichier trouvé qui respecte la sélection
                ok = False 
                for selection in selections:
                    if fnmatch(nom, selection):
                        # on a trouve un motif de selection qui marche
                        ok = True
                        break
                if ok:
                    fichiers.append(nom)
     
        # tris alphabétique sans tenir compte de la casse
        reperts.sort(key=lambda v: v.upper())
        fichiers.sort(key=lambda v: v.upper())
     
        # affichage
        okrep = False
        for fichier in fichiers:
            if not okrep: # n'afficher que les répert. ayant des fichiers sélectionnés
                print
                print repertoire
                okrep = True
            print "-"*niveau + fichier
     
        # traitement des sous-répertoires
        for repert in reperts:
            listefichiers(os.path.join(repertoire, repert), selections, niveau+1)
    Exemple d'utilisation:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    repertoire = r"C:\Python27\Tools"
    listefichiers(repertoire, ['*.txt', '*.jpg'])
    Ce qui affiche:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    C:\Python27\Tools\pynche
    -html40colors.txt
    -namedcolors.txt
    -README.txt
    -webcolors.txt
    -websafe.txt
     
    C:\Python27\Tools\pynche\X
    --rgb.txt
    --xlicense.txt
     
    C:\Python27\Tools\Scripts
    -README.txt
     
    C:\Python27\Tools\versioncheck
    -README.txt
     
    C:\Python27\Tools\webchecker
    -README.txt
    Le parcours récursif dans l'arborescence se fait "profondeur d'abord".

    Le nombre de '-' devant les fichiers représente la profondeur de leur chemin dans l'arborescence des répertoires.

    L'argument 'selections' est la liste des motifs 'joker' de sélection des fichiers.

    Seuls les répertoires ayant des fichiers sélectionnés sont affichés.

    En cas d'échec pour rentrer dans un répertoire, il est affiché l'erreur, mais le programme continu avec le répertoire suivant.

    Les répertoires et les fichiers sont affichés triés, et sans tenir compte de la casse (sinon, les majuscules seraient avant les minuscules).

    Ce code est facile à adapter.
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  5. #5
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 843
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 843
    Points : 7 151
    Points
    7 151
    Par défaut
    @tyrtamos

    En général la solution récursive est plus jolie qu'une solution itérative, mais tu sais aussi bien que moi que c'est moins rapide en règle générale.

    Dans ce genre de cas, c'est des milliers de fichiers, et la solution récursive je la trouve un peu limité...

    Mais le PO veut une solution récursive, donc... Pourquoi ce choix?
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  6. #6
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 471
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 471
    Points : 9 265
    Points
    9 265
    Billets dans le blog
    6
    Par défaut
    Bonjour fred1599,

    Je crois que dans ce genre de problème, on utilise souvent le mot "récursif" pour indiquer qu'on veut parcourir l'arbre.

    Il est vrai que certains problèmes appellent naturellement une solution récursive qui en plus parait élégante. En contrepartie, il y a toujours la limite de la pile de récursion Python (qu'on peut cependant accroitre) et ce n'est pas toujours la solution la plus rapide.

    Dans le code ci-dessus, il est assez facile de parcourir l'arbre de manière non-récursive: on fait une boucle pour empiler les répertoires, et on les traite un à un jusqu'à ce que la pile soit vide. En gérant en plus des niveaux, on pourrait passer facilement, si nécessaire, d'un parcours "profondeur d'abord" à un parcours "largeur d'abord".
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,
    Faire cela avec une fonction récursive se réduit à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import os
     
    def traverse(path, level=0):
        for name in os.listdir(path):
            fullpath = os.path.join(path, name)
            if not os.path.isdir(fullpath):
                for ext in ('.png', '.txt'):
                    if name.endswith(ext):
                        print (' ' * level, name)
            else:
                print (' ' * level, fullpath)
                traverse(fullpath, level=level+1)
    Après on peut bien sûr ajouter des considérations "non fonctionnelles" pour améliorer performance, traitement d'erreur, etc... mais seulement après et en évitant de changer la structure.

    En général la solution récursive est plus jolie qu'une solution itérative, mais tu sais aussi bien que moi que c'est moins rapide en règle générale.

    Dans ce genre de cas, c'est des milliers de fichiers, et la solution récursive je la trouve un peu limité...
    Vu le temps perdu par os.listdir à récupérer la liste des fichiers sur disque, est ce vraiment un problème?
    Plus généralement, si on vise à écrire du code rapide et performant, on choisira un autre langage, non?
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  8. #8
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 843
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 843
    Points : 7 151
    Points
    7 151
    Par défaut
    Vu le temps perdu par os.listdir à récupérer la liste des fichiers sur disque, est ce vraiment un problème?
    Je ne sais pas, il faudrait tester le timing entre ta solution et la solution os.walk(), car la difficulté entre l'utilisation de l'un et de l'autre est faible, autant prendre le plus performant dans ces cas là, non?

    Plus généralement, si on vise à écrire du code rapide et performant, on choisira un autre langage, non?
    Tout à fait d'accord, mais encore faut-il maîtriser d'autres langages.
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Je ne sais pas, il faudrait tester le timing entre ta solution et la solution os.walk(), car la difficulté entre l'utilisation de l'un et de l'autre est faible, autant prendre le plus performant dans ces cas là, non?
    Pas la peine de tester, os.walk étant aussi récursif, l'un comme l'autre n'iront pas plus vite que les disques.

    Le seul intérêt de s'appliquer à utiliser les bibliothèques standard n'est pas pour rechercher la "performance", mais pour avoir moins de code à maintenir, documenter.

    Reste le temps passé à écrire le code.
    Je ne suis pas certain qu'utiliser os.walk aide beaucoup pour faire ce que demande le P.O.: comme par exemple, gérer la profondeur, l'affichage (deep first) demandé => beaucoup de code juste pour adapter os.walk au besoin.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  10. #10
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 471
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 471
    Points : 9 265
    Points
    9 265
    Billets dans le blog
    6
    Par défaut
    Je viens de vérifier la rapidité du code que j'ai proposé plus haut.

    Sur un répertoire contenant 362 sous-répertoires et 15182 fichiers: l'affichage complet dans une console prend... moins de 8 secondes!

    Et on dit que Python est lent?
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par tyrtamos Voir le message
    Et on dit que Python est lent?
    Tous les langages interprétés sont "lents" comparés aux langages compilés.
    Python ne fait pas exception sauf à le booster avec une mécanique de JIT comme le fait PyPy ou le transformer en JavaScript pour l'exécuter avec le JIT de V8.

    Un des atouts de Python est de pouvoir prototyper rapidement, d'améliorer les performances plus tard, si nécessaire, de tout ou partie en les ré-écrivant en C/C++, Java.

    Dans le cas du parcours d'une arborescence disque, tous les codes dépendront des primitives de l'OS, du file system (cache), et de la rapidité des disques. Attendre 90-95% du temps le retour de l'équivalent d'os.listdir ne laissera que 5 à 10% pour améliorer les performances grâce au langage.

    Dit autrement, prendre un langage compilé allant 10 fois plus vite que Python permettrait dans ce cas de terminer le programme en 7.3s au lieu de 8s. Ce sera un "mieux" de 8 à 9 %, et non de 1000%.

    C'est ce qui fait que même si un algo itératif sera plus rapide qu'un algo récursif, "en général", dans ce cas particulier on s'en fout un peu.
    Comme la durée globale n'est pas du temps de calcul mais de l'attente des entrées sorties, seul ajouter des threads pourrait améliorer les choses.
    (mais est ce que les gains mériteront la mise au point d'un truc bien plus compliqué?).

    Tout cela est connu depuis fort longtemps sous le nom de loi de Amdhal.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. demande d'aide en python
    Par DARKSKIL dans le forum Général Python
    Réponses: 5
    Dernier message: 14/04/2013, 00h11
  2. Demande d'aide pour extraire des données Excel à l'aide python
    Par userinfo dans le forum Général Python
    Réponses: 5
    Dernier message: 05/01/2013, 11h45
  3. demande d'aide sur python
    Par dekiss dans le forum Général Python
    Réponses: 2
    Dernier message: 01/03/2012, 16h05
  4. Demande d'aide pour comprendre des syntaxes Python
    Par Cyberstein dans le forum Général Python
    Réponses: 13
    Dernier message: 31/12/2009, 22h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo