904 votes

Obtenir une liste de tous les sous-répertoires du répertoire courant

Existe-t-il un moyen de retourner une liste de tous les sous-répertoires du répertoire courant en Python ?

Je sais que vous pouvez le faire avec des fichiers, mais j'ai besoin d'obtenir la liste des répertoires à la place.

16 votes

Si vous recherchez une solution de type "pathlib", procédez comme suit [f for f in data_path.iterdir() if f.is_dir()] crédit : stackoverflow.com/a/44228436/1601580 . cela vous donne des noms de dossiers sous forme de chaînes. D'une certaine manière, cela exclut également . y .. Dieu merci. La solution Glob est également intéressante : glob.glob("/path/to/directory/*/") .

896voto

Blair Conrad Points 56195

Voulez-vous dire les sous-répertoires immédiats, ou chaque répertoire tout au long de l'arbre ?

Dans tous les cas, vous pouvez utiliser os.walk pour le faire :

os.walk(directory)

donnera un tuple pour chaque sous-répertoire. La première entrée du tuple 3 est un nom de répertoire, donc

[x[0] for x in os.walk(directory)]

devrait vous donner tous les sous-répertoires, de manière récursive.

Notez que la deuxième entrée du tuple est la liste des répertoires enfants de l'entrée en première position, vous pouvez donc utiliser cette option à la place, mais cela ne vous fera pas gagner beaucoup d'argent.

Cependant, vous pouvez l'utiliser simplement pour vous donner les répertoires enfants immédiats :

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

Ou consultez les autres solutions déjà postées, en utilisant os.listdir y os.path.isdir y compris ceux de " Comment obtenir tous les sous-répertoires immédiats en Python ".

3 votes

Une réponse si propre et agréable. Merci. Je n'étais pas familier avec next() et j'ai pensé que ce lien pourrait être utile à quiconque se trouve dans une situation similaire : stackoverflow.com/questions/1733004/python-next-function

42 votes

Pour toute personne concernée par les différences de performance entre os.walk y os.listdir + os.path.isdir solutions : Je viens de tester sur un répertoire avec 10 000 sous-répertoires (avec des millions de fichiers dans la hiérarchie en dessous) et les différences de performances sont négligeables. os.walk : "10 boucles, meilleur de 3 : 44,6 msec par boucle" et os.listdir + os.path.isdir : "10 boucles, meilleur de 3 : 45.1 msec par boucle"

4 votes

@kevinmicke essayez ce test de performance sur un disque réseau, je pense que vous trouverez que la performance est plutôt significative dans ce cas.

213voto

gahooa Points 38006
import os

d = '.'
[os.path.join(d, o) for o in os.listdir(d) 
                    if os.path.isdir(os.path.join(d,o))]

6 votes

Notez que dans cette approche, vous devez prendre en compte les problèmes d'abspathes s'ils ne sont pas exécutés sur '.'.

5 votes

Juste un conseil, si vous n'utilisez pas le cwd ('.'), cela ne fonctionnera pas à moins que vous fassiez un os.path.join sur o pour obtenir le chemin complet, sinon isdir(0) retournera toujours false

8 votes

Il semble que le poste ait été mis à jour avec des corrections pour les deux problèmes mentionnés ci-dessus.

43voto

Eli Bendersky Points 82298

Si vous avez besoin d'une solution récursive qui trouvera tous les sous-répertoires dans les sous-répertoires, utilisez walk comme proposé précédemment.

Si vous n'avez besoin que des répertoires enfants du répertoire courant, combinez os.listdir con os.path.isdir

7 votes

En utilisant pathlib est plus simple : [f for f in p.iterdir() if f.is_dir()]

3 votes

@CharlieParker : cette réponse a précédé pathlib de quelques années.

0 votes

Pourquoi ne pas écrire la réponse complète en une seule ligne ?

25voto

Charith Points 427

Implémenté en utilisant python-os-walk. ( http://www.pythonforbeginners.com/code-snippets-source-code/python-os-walk/ )

import os

print("root prints out directories only from what you specified")
print("dirs prints out sub-directories from root")
print("files prints out all files from root and directories")
print("*" * 20)

for root, dirs, files in os.walk("/var/log"):
    print(root)
    print(dirs)
    print(files)

0 votes

En utilisant pathlib est plus simple : [f for f in p.iterdir() if f.is_dir()]

11voto

KurtB Points 41

Merci pour les conseils, les gars. J'ai rencontré un problème avec les liens mous (récursion infinie) qui sont retournés comme des répertoires. Des liens mous ? On ne veut pas de liens mous qui puent ! Donc...

Cela ne rendait que les répertoires, pas les softlinks :

>>> import os
>>> inf = os.walk('.')
>>> [x[0] for x in inf]
['.', './iamadir']

2 votes

Qu'est-ce que [x[0] for x in inf] appelé en python pour que je puisse le rechercher ?

3 votes

@shinzou C'est une compréhension de la liste. Super utile. Regardez aussi les compréhensions de dict.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X