Domanda

Voglio essere in grado di elencare solo le directory all'interno di alcune cartelle. Questo significa che non voglio elencare i nomi dei file, né voglio sottocartelle aggiuntive.

Vediamo se un esempio aiuta. Nella directory corrente abbiamo:

>>> 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']

Tuttavia, non voglio elencare i nomi dei file. Né voglio sottocartelle come \ Lib \ curses. Essenzialmente quello che voglio funziona con quanto segue:

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

Tuttavia, mi chiedo se esiste un modo più semplice per ottenere gli stessi risultati. Ho l'impressione che l'utilizzo di os.walk solo per restituire il livello superiore sia inefficiente / troppo.

È stato utile?

Soluzione

Filtra il risultato usando os.path.isdir () (e usa os.path.join () per ottenere il percorso reale):

>>> [ 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']

Altri suggerimenti

os.walk

Usa os.walk con next funzione elemento:

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

Per Python < = 2.5 usa:

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

Come funziona

[1] è un generatore e chiamando dirnames otterrà il primo risultato sotto forma di una 3 tupla (dirpath, dirnames, nomi di file). Pertanto l'indice <=> restituisce solo il <=> da quella tupla.

Filtra l'elenco usando os.path.isdir per rilevare le directory.

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

Nota che, anziché fare os.listdir(os.getcwd()), è preferibile fare os.listdir(os.path.curdir). Una chiamata di funzione in meno ed è portatile.

Quindi, per completare la risposta, per ottenere un elenco di directory in una cartella:

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

Se preferisci i percorsi completi, usa questa funzione:

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 per aggiungere che l'uso di os.listdir () non " richiede molta elaborazione e os.walk (). molto semplice () [1] " . Questo perché os.walk () utilizza os.listdir () internamente. In effetti se li provi insieme:

>>>> 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

Il filtraggio di os.listdir () è leggermente più veloce.

Un modo molto più semplice ed elegante è usare questo:

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

Esegui questo script nella stessa cartella per cui desideri i nomi delle cartelle. Ti darà esattamente solo il nome delle cartelle immediate (anche quello senza il percorso completo delle cartelle).

Anche questo sembra funzionare (almeno su Linux):

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

essendo un principiante qui non posso ancora commentare direttamente, ma ecco una piccola correzione che vorrei aggiungere alla parte seguente di <> # 932;! <> # 918;! <> # 937;! <> # 932;!! <> # 918 ; & # 921; & # 927; & # 933; risposta di :

  

Se preferisci i percorsi completi, usa questa funzione:

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

per quelli ancora su Python < 2.4 : il costrutto interno deve essere un elenco anziché una tupla e quindi dovrebbe essere letto in questo modo:

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

altrimenti si ottiene un errore di sintassi.

Utilizzando la comprensione dell'elenco,

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

Penso che sia il modo più semplice

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

Per un elenco di nomi di percorsi completi preferisco questa versione alle altre soluzioni qui:

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))]

Un'opzione più sicura che non fallisce quando non c'è directory.

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 []

Ti piace?

>>>> [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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top