2011-08-23 17 views
21

Estoy queriendo una función para devolver una lista con directorios con una ruta especificada y una profundidad fija y pronto me di cuenta de que hay algunas alternativas. Estoy usando os.walk bastante pero el código comenzó a verse feo cuando se cuenta la profundidad, etc.Lista de directorios con una profundidad especificada en Python

¿Cuál es realmente la implementación más "ordenada"?

Respuesta

43

Si la profundidad es fijo, glob es una buena idea:

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

De lo contrario, no debería ser demasiado difícil de usar 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

su primer ejemplo usando glob es brillante y nunca me hubiera ido esa pista. ¡Un millón de gracias! – StefanE

3

Esto no es exactamente ordenada , pero bajo el sistema operativo tipo UNIX, también puede confiar en una herramienta del sistema como "buscar", y simplemente ejecutarlo como un programa externo, por ejemplo:

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

A continuación, puede redirigir la salida a alguna variable de cadena para su posterior manejo.

+0

Este devolvería directorios de profundidad 1 y 2. Para obtener solo los directorios de profundidad 2, habría que agregar '" -mindepth "," 2 "' a la lista de parámetros de llamada. –

+3

También puede hacer 'call (" buscar -maxdepth 2 -mindepth 2 -type d ", shell = True)'. – hatmatrix

2

Me gusta mucho la respuesta de phihag. Lo adapté para satisfacer mis necesidades.

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 

supongo que yo también podría hacerlo un generador con algo como esto:

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 

Crítica de bienvenida.

Cuestiones relacionadas