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 :

Lister les fichiers d'un répertoire de façon chronologique


Sujet :

Python

  1. #1
    Futur Membre du Club
    Profil pro
    data scientist
    Inscrit en
    Avril 2002
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : data scientist

    Informations forums :
    Inscription : Avril 2002
    Messages : 6
    Points : 7
    Points
    7
    Par défaut Lister les fichiers d'un répertoire de façon chronologique
    Bonjour,

    je cherche un moyen simple pour .... lister les fichiers d'un répertoire de façon chronologique.

    En fait, je sais comment lister les fichiers avec la commande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    import os
    for myfile in os.listdir(myDirectory):
        print myfile
    mais cette commande ne permet pas de choisir la méthode de tri, et liste les fichiers par ordre alphabetique.

    Est ce que vous avez des idées?

  2. #2
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    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 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    On peut avoir la date de dernière modif avec os.path.getmtime('nomdefichier'): cette cde donne le nb de secondes depuis l'epoc (référence de Python).

    Le principe sera donc d'utiliser la méthode de tri de Python, mais en demandant à ce que les comparaisons se fassent avec les dates et non les noms pendant le tri.

    Cela donne, si L est la liste des noms de fichiers fournis par os.listdir:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    chrono = lambda v: os.path.getmtime(os.path.join(myDirectory, v))
    L.sort(key = chrono)
    La liste L est alors classée par ordre chronologique.

    Tyrtamos
    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

  3. #3
    Futur Membre du Club
    Profil pro
    data scientist
    Inscrit en
    Avril 2002
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : data scientist

    Informations forums :
    Inscription : Avril 2002
    Messages : 6
    Points : 7
    Points
    7
    Par défaut
    Merci!

    En fait, le souci, c'est que je dispose d'une version de python 2.1 (impossible de disposer d'une version supérieure), le parametre key de la methode sort était inconnu...

    Comme je suis un intermittent du python, je n'avais pas touché à ce langage depuis 3 ans, je suis retourné sur des trucs que je comprenais et j'ai trouvé la solution suivante:

    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
    import os
    allfiles= []
    alltimes=[]
    sourcePath = 'D:\\Jython'
    for file in os.listdir(sourcePath):
    	if os.path.isfile(sourcePath + '/'+file):
    		filetime = os.path.getatime(sourcePath + '/' + file)
    		i = 0
    		if len(alltimes)==0:
    			allfiles.append(file)
    			alltimes.append(filetime)
    		else:
    			while i<len(alltimes) and filetime > alltimes[i]:
    				i = i + 1
    			alltimes.insert(i,filetime)
    			allfiles.insert(i,file)			
    for myfile in allfiles:
         ...
    Je sais c'est moche et pas optimisé, mais ça répond a mon problème. D'ailleurs, si vous avez une idée d'optimisation, je suis prenneur.

    Fred

  4. #4
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    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 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Petit cadeau: voilà une fonction de tri (par insertion) qui accepte le 'key=':

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    def tri(L, key=lambda v: v):
        for i in xrange(1,len(L)):
            if key(L[i])<key(L[i-1]):
                for k in xrange(0,i):
                    if key(L[i])<key(L[k]):
                        X=L.pop(i)
                        L.insert(k,X)
                        break
    Comme c'est un tri par insertion, il sera un peu moins rapide pour les grandes listes que le sort() de Python.

    Comme le sort() de Python, il trie la liste "sur place": elle est donc modifiée. Il est cependant facile de l'adapter pour qu'elle revoie une autre liste.

    Pour des très grandes listes, il est également facile d'augmenter sa rapidité en ajoutant une recherche par dichotomie (voir sur mon site: http://python.jpvweb.com/mesrecettes.../tri_insertion).

    Avec cette fonction, ma solution à ton pb devient:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    chrono = lambda v: os.path.getmtime(os.path.join(myDirectory, v))
    tri(L, chrono)
    A noter que tu peux utiliser le même principe pour trier selon d'autres critères, par exemple la taille des fichiers.

    Tyrtamos
    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
    Futur Membre du Club
    Profil pro
    data scientist
    Inscrit en
    Avril 2002
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : data scientist

    Informations forums :
    Inscription : Avril 2002
    Messages : 6
    Points : 7
    Points
    7
    Par défaut
    Merci beaucoup.

    Ma version a été testée et validée dans ma boite... il fallait faire super vite hier.

    A la prochaine relivraison (le plus tard possible j'espère), j'optimiserai le code.

    A +

    Fred

  6. #6
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Se passer de la fonction de tri de Python, écrite en C et donc performante ?
    Tss tss tss....



    Il faut penser que sort() trie sur la base du premier item d’élément quand les éléments sont des séquences de plus d'un item.
    Par contre la fonction itemgetter() n’est arrivée que dans la version 2.4, on est donc obligé de créer des couples (temps,nom de fichier) pour pouvoir lancer sort() sur la liste créée, et non pas (nom de fichier, temps).

    J’ai installé Python 2.1.3 pour vérifier que les codes suivants tournent sous cette version.



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from os.path import normpath,getatime,isfile
    from os import listdir
     
    Path = normpath(raw_input('Entrer le nom du dossier a explorer : ')+'// ')[0:-1]
     
    fichiers = [ (getatime(Path+fifi),fifi) 
                  for fifi in listdir(Path) if isfile(Path+fifi) ]
    fichiers.sort()
     
    print '\n'+'\n'.join(map(repr,fichiers))




    On peut transformer le temps en chaîne lisible.
    Mais attention, pour continuer à pouvoir faire le tri en fonction du temps, il faut que les dates obtenues soient du type année/mois/jour heure/minutes/secondes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    from os.path import normpath,getatime,isfile
    from os import listdir
    from time import strftime,gmtime
     
    Path = normpath(raw_input('Entrer le nom du dossier a explorer : ')+'// ')[0:-1]
     
    fichiers = [ (strftime('%Y/%m/%d %H:%M:%S',gmtime(getatime(Path+fifi))),fifi)
                  for fifi in listdir(Path) if isfile(Path+fifi) ]
    fichiers.sort()
     
    print '\n'+'\n'.join(map(repr,fichiers))






    J'ai fait une comparaison, toujours en Python 2.1.3


    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    from os.path import normpath,getatime,isfile
    from os import listdir
    from time import strftime,gmtime,clock
     
    sourcePath = normpath(raw_input('\nEntrer le nom du dossier a explorer : ')+'// ')[0:-1]
    print
     
    LC,LCstrf,WHILE,WHILEsimpl,FOR = [],[],[],[],[]
     
    for w in xrange(5):
     
        # code eyquem avec temps depuis epoch
        te = clock()
        fichiers = [ (getatime(sourcePath+fifi),fifi) for fifi in listdir(sourcePath)
                     if isfile(sourcePath+fifi) ]
        fichiers.sort()
        tf = clock()
        LC.append(tf-te)
        if w==0: A = [ v for u,v in fichiers]
     
     
        # code eyquem avec temps transforme par gmtime et strftime
        te = clock()
        fichiers = [ (strftime('%Y/%m/%d %H:%M:%S',gmtime(getatime(sourcePath+fifi))),fifi)
                      for fifi in listdir(sourcePath)
                      if isfile(sourcePath+fifi) ]
        fichiers.sort()
        tf = clock()
        LCstrf.append(tf-te)
        if w==0: B = [ v for u,v in fichiers]
     
     
        # code de fredm
        allfiles,alltimes = [],[]
        te = clock()
        for fule in listdir(sourcePath):
            if isfile(sourcePath +fule):
                filetime = getatime(sourcePath + fule)
                i = 0
                if len(alltimes)==0:
                    allfiles.append(fule)
                    alltimes.append(filetime)
                else:
                    while i<len(alltimes) and filetime > alltimes[i]:
                        i = i + 1
                    alltimes.insert(i,filetime)
                    allfiles.insert(i,fule)
        tf = clock()
        WHILE.append(tf-te)
        if w==0: C = allfiles
     
     
        # code de fredm simplifie
        allfiles,alltimes = [],[]
        te = clock()
        for fule in listdir(sourcePath):
            if isfile(sourcePath +fule):
                filetime = getatime(sourcePath + fule)
                j = 0
                while j<len(alltimes) and filetime > alltimes[j]:
                    j = j + 1
                alltimes.insert(j,filetime)
                allfiles.insert(j,fule)
        tf = clock()
        WHILEsimpl.append(tf-te)
        if w==0: D = allfiles
     
     
        # code de fredm transforme en iteration for
        allfiles,alltimes = [],[]
        te = clock()
        k = 0
        for fule in listdir(sourcePath):
            if isfile(sourcePath +fule):
                filetime = getatime(sourcePath + fule)
                for k in xrange(len(alltimes)):
                    if filetime < alltimes[k]: break
                    elif k==len(alltimes)-1: k+=1
                alltimes.insert(k,filetime)
                allfiles.insert(k,fule)
        tf = clock()
        FOR.append(tf-te)
        if w==0: E = allfiles
     
     
    bool ={0:'False',1:'True'}
    for x,X in (('B',B),('C',C),('D',D),('E',E)):
        print 'A=='+x+'  est ' + bool[A==X]
    A.sort()
    B.sort()
    C.sort()
    D.sort()
    E.sort()
    print 'sorted(A)==sorted(B)==sorted(C)==sorted(D)==sorted(E)  est ' + bool[A==B==C==D==E]
     
     
    t1,t2,t3,t4,t5 = min(LC),min(LCstrf),min(WHILE),min(WHILEsimpl),min(FOR)
    print '\nTaille du dossier examine : '+str(len(A))
    print '  100.0 %\t(getatime(Path+fifi),fifi) for fifi in listdir(Path)'
    print ' ',round(t2*100/t1,1),"%\t(strftime('%Y..%S',gmtime(getatime(Path+fifi))),fifi) for.."
    print ' ',round(t3*100/t1,1),'%\tcode de fredm'
    print ' ',round(t4*100/t1,1),'%\tcode de fredm simplifie'
    print ' ',round(t5*100/t1,1),'%\tcode de fredm transforme en iteration for'


    A==B est True....A==C est False....A==D est False....A==E est True
    sorted(A)==sorted(B)==sorted(C)==sorted(D)==sorted(E) est True

    Taille du dossier examine : 8
    ..100.0 %.............((getatime(Path+fifi),fifi) for fifi in listdir(Path)
    ..107.0 %.............((strftime('%Y..%S',gmtime(getatime(Path+fifi))),fifi) for..
    ..104.7 %.............(code de fredm
    ..104.8 %.............(code de fredm simplifie
    ..106.9 %.............(code de fredm transforme en iteration for

    A==B est True....A==C est False....A==D est False....A==E est False
    sorted(A)==sorted(B)==sorted(C)==sorted(D)==sorted(E) est True

    Taille du dossier examine : 183
    ..100.0 %.............((getatime(Path+fifi),fifi) for fifi in listdir(Path)
    ..108.7 %.............((strftime('%Y..%S',gmtime(getatime(Path+fifi))),fifi) for..
    ..151.2 %.............(code de fredm
    ..150.8 %.............(code de fredm simplifie
    ..186.8 %.............(code de fredm transforme en iteration for

    A==B est True....A==C est False....A==D est False....A==E est False
    sorted(A)==sorted(B)==sorted(C)==sorted(D)==sorted(E) est True

    Taille du dossier examine : 1578..100.0 %.............(getatime(Path+fifi),fifi) for fifi in listdir(Path)
    ..108.5 %.............(strftime('%Y..%S',gmtime(getatime(Path+fifi))),fifi) for..
    ..552.9 %.............code de fredm
    ..556.3 %.............code de fredm simplifie
    ..590.9 %.............code de fredm transforme en iteration for

    Le dernier test a été fait avec le dossier C:\WINNT\system32




    • Un tri avec sort() est effectivement plus rapide.
    • Transformer le temps en chaîne lisible n’allonge l’exécution que dans une proportion constante de 8 %.
    • Par contre le code de fredm est d’autant plus long que la taille du dossier est grande.




    Un code de fredm dans lequel j’ai transformé la boucle while en boucle for se révèle le plus long de tous.

  7. #7
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    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 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Bonjour eyquem,

    Citation Envoyé par eyquem Voir le message
    Se passer de la fonction de tri de Python, écrite en C et donc performante ?
    Tss tss tss....
    Tu as raison: aucune fonction de tri codé en Python n'est capable d'approcher les performances de sort(). Mais ma solution suffisait largement pour trier des répertoires.

    Cependant, allons-y: tant qu'à pallier l'absence de 'key=' dans le sort() du Python 2.1, autant le refabriquer comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    def tri(L, key=lambda v: v):
        R = [[key(elem), elem] for elem in L]
        R.sort()
        return [elem[1] for elem in R]
    On utilise alors

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    L = tri(L, lambda v: os.path.getmtime(os.path.join(myDirectory, v)))
    comme on utiliserait avec Python 2.6:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    L.sort(L, key=lambda v: os.path.getmtime(os.path.join(myDirectory, v)))
    Autre solution: dans la doc du Python 2.1, on dit que sort possède une fonction optionnelle de comparaison ("s.sort([cmpFct]): sort the items of s in place"). Il suffirait de créer cette fonction comparant les dates:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    chrono = lambda v: os.path.getmtime(os.path.join(myDirectory, v))
    def comp(v1, v2):
        return cmp(chrono(v1),chrono(v2))
    La solution deviendrait alors, par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    myDirectory = r"C:\Python26\Lib"
    L = os.listdir(myDirectory)
    L.sort(comp)
    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

  8. #8
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Citation Envoyé par tyrtamos Voir le message
    Cependant, allons-y: tant qu'à pallier l'absence de 'key=' dans le sort() du Python 2.1, autant le refabriquer comme suit:
    Cependant, allons-y: tant qu'à palier l'absence de sorted en Python < 2.4, autant le refabriquer comme suit:
    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
    try:
        sorted
    except NameError:
        def sorted(iterable, cmp=None, key=None, reverse=False):
            if key is None:
                l = list(iterable)
                if cmp is None:
                    # Python < 2.3 n'accepte pas None comme argument de cmp
                    l.sort()
                else:
                    l.sort(cmp=cmp)
            else:
                l = [(key(v),v) for v in iterable]
                if cmp is None:
                    l.sort()
                else:
                    l.sort(cmp=lambda x,y:cmp(x[0],y[0]))
                l = [v for k,v in l]
            if reverse:
                l.reverse()
            return l
    Le try/except permet de s'assurer qu'on ne redéfinira pas sorted s'il existe déjà (càd si on utilise Python >= 2.4). Je pense avoir reproduit le comportement de sorted: si on précise à la fois une fonction de comparaison et une fonction key, ce seront les clés extraites des éléments qui seront passées en argument à la fonction de comparaison.

    [EDIT:] Fonction corrigée pour fonctionner correctement avec Python < 2.3 (j'espère)

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

Discussions similaires

  1. Lister les fichiers d'un répertoire dans une feuille Excel
    Par AlainTech dans le forum Contribuez
    Réponses: 3
    Dernier message: 10/03/2016, 14h14
  2. [C++/Unix] Lister les fichiers d'un répertoire
    Par bouazza92 dans le forum Linux
    Réponses: 5
    Dernier message: 10/12/2013, 22h07
  3. Lister les fichiers d'un répertoire (ordre alphabétique)
    Par Mysti¢ dans le forum Général Python
    Réponses: 2
    Dernier message: 15/01/2007, 17h10
  4. lister les fichiers d'un répertoire et les ouvrir
    Par thong36 dans le forum Langage
    Réponses: 1
    Dernier message: 18/10/2006, 10h43
  5. [CF][PPC/C#] Comment lister les fichiers d'un répertoire ?
    Par dady dans le forum Windows Mobile
    Réponses: 18
    Dernier message: 20/05/2005, 14h35

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