2011-08-23 24 views
21

Voglio una funzione per restituire una lista con le directory con un percorso specificato e una profondità fissa e presto ci sono state alcune alternative. Sto usando os.walk parecchio, ma il codice ha iniziato a sembrare brutto quando ho contato la profondità, ecc.Elenca le directory con una profondità specificata in Python

Qual è l'implementazione più "pulita"?

risposta

43

Se la profondità è fisso, glob è una buona idea:

import glob,os.path 
filesDepth3 = glob.glob('*/*/*') 
dirsDepth3 = filter(lambda f: os.path.isdir(f), filesDepth3) 

In caso contrario, non dovrebbe essere troppo difficile da usare os.walk:

import os,string 
path = '.' 
path = os.path.normpath(path) 
res = [] 
for root,dirs,files in os.walk(path, topdown=True): 
    depth = root[len(path) + len(os.path.sep):].count(os.path.sep) 
    if depth == 2: 
     # We're currently two directories in, so all subdirs have depth 3 
     res += [os.path.join(root, d) for d in dirs] 
     dirs[:] = [] # Don't recurse any deeper 
print(res) 
+0

il tuo primo esempio con glob è geniale e non avrei mai fatto quella traccia. Grazie mille! – StefanE

3

Questo non è esattamente ordinata , ma sotto un SO simile a UNIX, puoi anche fare affidamento su uno strumento di sistema come "trova", e basta eseguirlo come un programma esterno, ad esempio:

from subprocess import call 
call(["find", "-maxdepth", "2", "-type", "d"]) 

È quindi possibile reindirizzare l'output su alcune variabili stringa per ulteriori informazioni.

+0

Questo restituirebbe le directory di profondità 1 e 2. Per ottenere solo le directory di profondità 2, si dovrebbe aggiungere "" -mindepth "," 2 "' alla lista dei parametri di chiamata. –

+3

Puoi anche fare call ("find -maxdepth 2 -mindepth 2 -type d", shell = True) '. – hatmatrix

2

Mi piace molto la risposta di phihag. L'ho adattato alle mie esigenze.

import fnmatch,glob 
def fileNamesRetrieve(top, maxDepth, fnMask ): 
    someFiles = [] 
    for d in range(1, maxDepth+1): 
     maxGlob = "/".join("*" * d) 
     topGlob = os.path.join(top, maxGlob) 
     allFiles = glob.glob(topGlob) 
     someFiles.extend([ f for f in allFiles if fnmatch.fnmatch(os.path.basename(f), fnMask) ]) 
    return someFiles 

Credo che avrei potuto anche fare un generatore con qualcosa di simile:

def fileNamesRetrieve(top, maxDepth, fnMask ): 
    for d in range(1, maxDepth+1): 
     maxGlob = "/".join("*" * d) 
     topGlob = os.path.join(top, maxGlob) 
     allFiles = glob.glob(topGlob) 
     if fnmatch.fnmatch(os.path.basename(f), fnMask): 
      yield f 

Critica benvenuto.

Problemi correlati