Pregunta

Quiero poder enumerar solo los directorios dentro de alguna carpeta. Esto significa que no quiero que aparezcan nombres de archivos, ni quiero subcarpetas adicionales.

Veamos si un ejemplo ayuda. En el directorio actual tenemos:

>>> os.listdir(os.getcwd())
['cx_Oracle-doc', 'DLLs', 'Doc', 'include', 'Lib', 'libs', 'LICENSE.txt', 'mod_p
ython-wininst.log', 'NEWS.txt', 'pymssql-wininst.log', 'python.exe', 'pythonw.ex
e', 'README.txt', 'Removemod_python.exe', 'Removepymssql.exe', 'Scripts', 'tcl',
 'Tools', 'w9xpopen.exe']

Sin embargo, no quiero que aparezcan nombres de archivos. Tampoco quiero subcarpetas como \ Lib \ curses. Esencialmente, lo que quiero funciona con lo siguiente:

>>> for root, dirnames, filenames in os.walk('.'):
...     print dirnames
...     break
...
['cx_Oracle-doc', 'DLLs', 'Doc', 'include', 'Lib', 'libs', 'Scripts', 'tcl', 'Tools']

Sin embargo, me pregunto si hay una manera más simple de lograr los mismos resultados. Tengo la impresión de que usar os.walk solo para devolver el nivel superior es ineficiente / demasiado.

¿Fue útil?

Solución

Filtre el resultado usando os.path.isdir () (y use os.path.join () para obtener la ruta real):

>>> [ name for name in os.listdir(thedir) if os.path.isdir(os.path.join(thedir, name)) ]
['ctypes', 'distutils', 'encodings', 'lib-tk', 'config', 'idlelib', 'xml', 'bsddb', 'hotshot', 'logging', 'doc', 'test', 'compiler', 'curses', 'site-packages', 'email', 'sqlite3', 'lib-dynload', 'wsgiref', 'plat-linux2', 'plat-mac']

Otros consejos

os.walk

Use os.walk con next función del elemento:

next(os.walk('.'))[1]

Para Python < = 2.5 use:

os.walk('.').next()[1]

Cómo funciona esto

[1] es un generador y al llamar a dirnames obtendrá el primer resultado en forma de 3 tuplas (dirpath, dirnames, nombres de archivo). Por lo tanto, el índice <=> devuelve solo el <=> de esa tupla.

Filtre la lista usando os.path.isdir para detectar directorios.

filter(os.path.isdir, os.listdir(os.getcwd()))
directories=[d for d in os.listdir(os.getcwd()) if os.path.isdir(d)]

Tenga en cuenta que, en lugar de hacer os.listdir(os.getcwd()), es preferible hacer os.listdir(os.path.curdir). Una llamada de función menos, y es tan portátil.

Entonces, para completar la respuesta, para obtener una lista de directorios en una carpeta:

def listdirs(folder):
    return [d for d in os.listdir(folder) if os.path.isdir(os.path.join(folder, d))]

Si prefiere nombres de ruta completos, use esta función:

def listdirs(folder):
    return [
        d for d in (os.path.join(folder, d1) for d1 in os.listdir(folder))
        if os.path.isdir(d)
    ]

Solo para agregar que usar os.listdir () no " toma mucho procesamiento versus muy simple os.walk (). next () [1] " . Esto se debe a que os.walk () usa os.listdir () internamente. De hecho, si los prueba juntos:

>>>> import timeit
>>>> timeit.timeit("os.walk('.').next()[1]", "import os", number=10000)
1.1215229034423828
>>>> timeit.timeit("[ name for name in os.listdir('.') if os.path.isdir(os.path.join('.', name)) ]", "import os", number=10000)
1.0592019557952881

El filtrado de os.listdir () es muy ligeramente más rápido.

Una forma mucho más simple y elegante es usar esto:

 import os
 dir_list = os.walk('.').next()[1]
 print dir_list

Ejecute este script en la misma carpeta para la que desea nombres de carpeta. Le dará exactamente el nombre inmediato de las carpetas (también sin la ruta completa de las carpetas).

Esto parece funcionar también (al menos en Linux):

import glob, os
glob.glob('*' + os.path.sep)

siendo un novato aquí, todavía no puedo comentar directamente, pero aquí hay una pequeña corrección que me gustaría agregar a la siguiente parte de & # 932; & # 918; & # 937; & # 932; & # 918 ; & # 921; & # 927; & # 933; respuesta de :

  

Si prefiere nombres de ruta completos, use esta función:

def listdirs(folder):  
  return [
    d for d in (os.path.join(folder, d1) for d1 in os.listdir(folder))
    if os.path.isdir(d)
]

para aquellos que todavía están en python < 2.4 : la construcción interna debe ser una lista en lugar de una tupla y, por lo tanto, debería leer así:

def listdirs(folder):  
  return [
    d for d in [os.path.join(folder, d1) for d1 in os.listdir(folder)]
    if os.path.isdir(d)
  ]

de lo contrario, se obtiene un error de sintaxis.

Usando la comprensión de la lista,

[a for a in os.listdir() if os.path.isdir(a)]

Creo que es la forma más simple

[x for x in os.listdir(somedir) if os.path.isdir(os.path.join(somedir, x))]

Para obtener una lista de nombres de ruta completos, prefiero esta versión a las otras soluciones aquí:

def listdirs(dir):
    return [os.path.join(os.path.join(dir, x)) for x in os.listdir(dir) 
        if os.path.isdir(os.path.join(dir, x))]
scanDir = "abc"
directories = [d for d in os.listdir(scanDir) if os.path.isdir(os.path.join(os.path.abspath(scanDir), d))]

Una opción más segura que no falla cuando no hay directorio.

def listdirs(folder):
    if os.path.exists(folder):
         return [d for d in os.listdir(folder) if os.path.isdir(os.path.join(folder, d))]
    else:
         return []

¿Te gusta así?

>>>> [path for path in os.listdir(os.getcwd()) if os.path.isdir(path)]
-- This will exclude files and traverse through 1 level of sub folders in the root

def list_files(dir):
    List = []
    filterstr = ' '
    for root, dirs, files in os.walk(dir, topdown = True):
        #r.append(root)
        if (root == dir):
            pass
        elif filterstr in root:
            #filterstr = ' '
            pass
        else:
            filterstr = root
            #print(root)
            for name in files:
                print(root)
                print(dirs)
                List.append(os.path.join(root,name))
            #print(os.path.join(root,name),"\n")
                print(List,"\n")

    return List
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top