Je veux pouvoir énumérer seulement les répertoires à l'intérieur d'un dossier. Cela signifie que je ne veux pas que les noms de fichiers soient listés, ni de sous-dossiers supplémentaires.
Voyons si un exemple peut aider. Dans le répertoire actuel, nous avons:
>>> 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']
Cependant, je ne veux pas que les noms de fichiers soient listés. Je ne veux pas non plus de sous-dossiers tels que\Lib\curses. Essentiellement, ce que je veux fonctionne avec les éléments suivants:
>>> for root, dirnames, filenames in os.walk('.'):
... print dirnames
... break
...
['cx_Oracle-doc', 'DLLs', 'Doc', 'include', 'Lib', 'libs', 'Scripts', 'tcl', 'Tools']
Cependant, je me demande s’il existe un moyen plus simple d’obtenir les mêmes résultats. J'ai l'impression que l'utilisation de os.walk uniquement pour renvoyer le niveau supérieur est inefficace/excessive.
Filtrez le résultat en utilisant os.path.isdir () (et utilisez os.path.join () pour obtenir le vrai chemin):
>>> [ 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']
Utilisation os.walk
avec next
fonction de l’élément:
next(os.walk('.'))[1]
Pour Python <= 2.5 , utilisez:
os.walk('.').next()[1]
os.walk
est un générateur et appeler next
obtiendra le premier résultat sous la forme d'un 3-Tuple (dirpath, dirnames, noms de fichiers). Ainsi, le [1]
index ne renvoie que le dirnames
de ce tuple.
Filtrez la liste en utilisant os.path.isdir pour détecter les répertoires.
filter(os.path.isdir, os.listdir(os.getcwd()))
directories=[d for d in os.listdir(os.getcwd()) if os.path.isdir(d)]
Notez que, au lieu de os.listdir(os.getcwd())
, il est préférable de faire os.listdir(os.path.curdir)
. Un appel de fonction de moins, et il est aussi portable.
Donc, pour compléter la réponse, obtenir une liste de répertoires dans un dossier:
def listdirs(folder):
return [d for d in os.listdir(folder) if os.path.isdir(os.path.join(folder, d))]
Si vous préférez des chemins d'accès complets, utilisez cette fonction:
def listdirs(folder):
return [
d for d in (os.path.join(folder, d1) for d1 in os.listdir(folder))
if os.path.isdir(d)
]
Juste pour ajouter que l'utilisation de os.listdir () ne fait pas "prend beaucoup de traitement vs très simple os.walk (). Next () [1]". En effet, os.walk () utilise os.listdir () en interne. En fait si vous les testez ensemble:
>>>> 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
Le filtrage de os.listdir () est très légèrement plus rapide.
Une manière beaucoup plus simple et élégante consiste à utiliser ceci:
import os
dir_list = os.walk('.').next()[1]
print dir_list
Exécutez ce script dans le même dossier pour lequel vous voulez des noms de dossier. Il vous donnera exactement le nom du dossier immédiat uniquement (sans le chemin complet des dossiers).
Cela semble fonctionner aussi (au moins sur Linux):
import glob, os
glob.glob('*' + os.path.sep)
Utilisation de la compréhension de liste,
[a for a in os.listdir() if os.path.isdir(a)]
Je pense que c'est le moyen le plus simple
étant un débutant ici, je ne peux pas encore commenter directement, mais voici une petite correction que je voudrais ajouter à la partie suivante de réponse de ΤΖΩΤΖΙΟΥ :
Si vous préférez des chemins d'accès complets, utilisez cette fonction:
def listdirs(folder): return [ d for d in (os.path.join(folder, d1) for d1 in os.listdir(folder)) if os.path.isdir(d) ]
pour ceux qui sont toujours sur python <2.4 : la construction interne doit être une liste au lieu d'un tuple et doit donc lire comme ceci:
def listdirs(folder):
return [
d for d in [os.path.join(folder, d1) for d1 in os.listdir(folder)]
if os.path.isdir(d)
]
sinon, on obtient une erreur de syntaxe.
[x for x in os.listdir(somedir) if os.path.isdir(os.path.join(somedir, x))]
Pour une liste de noms de chemins complets, je préfère cette version à l'autre solutions ici:
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))]
Ainsi?
>>>> [path for path in os.listdir(os.getcwd()) if os.path.isdir(path)]
Une option plus sûre qui n'échoue pas lorsqu'il n'y a pas de répertoire.
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 []