Existe-t-il un moyen de renvoyer une liste de tous les sous-répertoires du répertoire actuel en Python?
Je sais que vous pouvez le faire avec des fichiers, mais je dois plutôt obtenir la liste des répertoires.
Existe-t-il un moyen de renvoyer une liste de tous les sous-répertoires du répertoire actuel en Python?
Je sais que vous pouvez le faire avec des fichiers, mais je dois plutôt obtenir la liste des répertoires.
Réponses:
Voulez-vous dire des sous-répertoires immédiats ou tous les répertoires dans l'arborescence?
Dans les deux cas, vous pouvez utiliser os.walk
pour cela:
os.walk(directory)
produira un tuple pour chaque sous-répertoire. La première entrée du triplet est un nom de répertoire, donc
[x[0] for x in os.walk(directory)]
devrait vous donner tous les sous-répertoires, récursivement.
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 l'utiliser à la place, mais il est peu probable que vous économisiez beaucoup.
Cependant, vous pouvez l'utiliser uniquement pour vous donner les répertoires enfants immédiats:
next(os.walk('.'))[1]
Ou consultez les autres solutions déjà publiées, en utilisant os.listdir
et os.path.isdir
, y compris celles de " Comment obtenir tous les sous-répertoires immédiats en Python ".
os.walk('.').next()[1]
ou os.walk('.').__next__()[1]
directement. À la place, utilisez la fonction intégrée next()
, qui est disponible à la fois dans Python 2 (voir doc) et Python 3 (voir doc) . Par exemple: next(os.walk('.'))[1]
.
os.walk('.').next()[1]
directement?
iteraror.__next__()
s'agit d'une méthode interne et l' iterator.next()
utilisation doit être transférée vers la fonction intégrée next()
selon PEP-3114. Voir PEP-3114 qui a été approuvé en 2007.
os.walk
et os.listdir
+ os.path.isdir
: je viens de tester sur un répertoire avec 10 000 sous-répertoires (avec des millions de fichiers dans la hiérarchie ci-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"
import os
d = '.'
[os.path.join(d, o) for o in os.listdir(d)
if os.path.isdir(os.path.join(d,o))]
os.path.join
on o
pour obtenir le chemin complet, sinon isdir(0)
retournera toujours faux
os.path.join
deux fois, vous pouvez d'abord rejoindre puis filtrer la liste en utilisant os.path.isdir
: filter(os.path.isdir, [os.path.join(d, o) for o in os.listdir(d)])
Vous pouvez simplement utiliser glob.glob
from glob import glob
glob("/path/to/directory/*/")
N'oubliez pas le suivi /
après le *
.
/
dans les noms
/
être le séparateur de dossiers, procédez comme glob(os.path.join(path_to_directory, "*", ""))
recursive=True
Beaucoup plus agréable que ci-dessus, car vous n'avez pas besoin de plusieurs os.path.join () et vous obtiendrez le chemin complet directement (si vous le souhaitez), vous pouvez le faire en Python 3.5 et supérieur.
subfolders = [ f.path for f in os.scandir(folder) if f.is_dir() ]
Cela donnera le chemin d'accès complet au sous-répertoire. Si vous souhaitez uniquement utiliser le nom du sous-répertoire f.name
au lieu def.path
https://docs.python.org/3/library/os.html#os.scandir
Légèrement OT: Si vous avez besoin de tous les sous-dossiers de manière récursive et / ou de tous les fichiers récursivement , jetez un œil à cette fonction, qui est plus rapide que os.walk
& glob
et renverra une liste de tous les sous-dossiers ainsi que tous les fichiers à l'intérieur de ces (sous-) sous-dossiers: https://stackoverflow.com/a/59803793/2441026
Si vous ne souhaitez que tous les sous-dossiers de manière récursive :
def fast_scandir(dirname):
subfolders= [f.path for f in os.scandir(dirname) if f.is_dir()]
for dirname in list(subfolders):
subfolders.extend(fast_scandir(dirname))
return subfolders
Renvoie une liste de tous les sous-dossiers avec leurs chemins d'accès complets. C'est encore plus rapide que os.walk
et beaucoup plus rapide que glob
.
Une analyse de toutes les fonctions
tl; dr:
- Si vous souhaitez obtenir tous les sous - répertoires immédiats pour une utilisation de dossier os.scandir
.
- Si vous souhaitez obtenir tous les sous-répertoires, même imbriqués , utilisez os.walk
ou - un peu plus vite - la fast_scandir
fonction ci-dessus.
- Ne jamais utiliser os.walk
uniquement pour les sous-répertoires de niveau supérieur, car cela peut être des centaines (!) Fois plus lent que os.scandir
.
os.walk
sera le dossier de base. Vous n'aurez donc pas que des sous-répertoires. Vous pouvez utiliser fu.pop(0)
pour le supprimer.Résultats :
os.scandir took 1 ms. Found dirs: 439
os.walk took 463 ms. Found dirs: 441 -> it found the nested one + base folder.
glob.glob took 20 ms. Found dirs: 439
pathlib.iterdir took 18 ms. Found dirs: 439
os.listdir took 18 ms. Found dirs: 439
Testé avec W7x64, Python 3.8.1.
# -*- coding: utf-8 -*-
# Python 3
import time
import os
from glob import glob
from pathlib import Path
directory = r"<insert_folder>"
RUNS = 1
def run_os_walk():
a = time.time_ns()
for i in range(RUNS):
fu = [x[0] for x in os.walk(directory)]
print(f"os.walk\t\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found dirs: {len(fu)}")
def run_glob():
a = time.time_ns()
for i in range(RUNS):
fu = glob(directory + "/*/")
print(f"glob.glob\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found dirs: {len(fu)}")
def run_pathlib_iterdir():
a = time.time_ns()
for i in range(RUNS):
dirname = Path(directory)
fu = [f for f in dirname.iterdir() if f.is_dir()]
print(f"pathlib.iterdir\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found dirs: {len(fu)}")
def run_os_listdir():
a = time.time_ns()
for i in range(RUNS):
dirname = Path(directory)
fu = [os.path.join(directory, o) for o in os.listdir(directory) if os.path.isdir(os.path.join(directory, o))]
print(f"os.listdir\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found dirs: {len(fu)}")
def run_os_scandir():
a = time.time_ns()
for i in range(RUNS):
fu = [f.path for f in os.scandir(directory) if f.is_dir()]
print(f"os.scandir\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms.\tFound dirs: {len(fu)}")
if __name__ == '__main__':
run_os_scandir()
run_os_walk()
run_glob()
run_pathlib_iterdir()
run_os_listdir()
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 actuel, combinez-les os.listdir
avecos.path.isdir
Je préfère utiliser un filtre ( https://docs.python.org/2/library/functions.html#filter ), mais ce n'est qu'une question de goût.
d='.'
filter(lambda x: os.path.isdir(os.path.join(d, x)), os.listdir(d))
Implémenté cela 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)
Vous pouvez obtenir la liste des sous-répertoires (et fichiers) dans Python 2.7 en utilisant os.listdir (chemin)
import os
os.listdir(path) # list of subdirectories and files
os.listdir
liste des contenus du répertoire, y compris les fichiers.
print("\nWe are listing out only the directories in current directory -")
directories_in_curdir = filter(os.path.isdir, os.listdir(os.curdir))
print(directories_in_curdir)
files = filter(os.path.isfile, os.listdir(os.curdir))
print("\nThe following are the list of all files in the current directory -")
print(files)
Python 3.4 a introduit le pathlib
module dans la bibliothèque standard, qui fournit une approche orientée objet pour gérer les chemins du système de fichiers:
from pathlib import Path
p = Path('./')
# List comprehension
[f for f in p.iterdir() if f.is_dir()]
# The trailing slash to glob indicated directories
# This will also include the current directory '.'
list(p.glob('**/'))
Pathlib est également disponible sur Python 2.7 via le module pathlib2 sur PyPi.
for f in filter(Path.is_dir, p.iterdir()):
Depuis que je suis tombé sur ce problème en utilisant les chemins Python 3.4 et Windows UNC, voici une variante pour cet environnement:
from pathlib import WindowsPath
def SubDirPath (d):
return [f for f in d.iterdir() if f.is_dir()]
subdirs = SubDirPath(WindowsPath(r'\\file01.acme.local\home$'))
print(subdirs)
Pathlib est nouveau dans Python 3.4 et facilite beaucoup l'utilisation des chemins sous différents systèmes d'exploitation: https://docs.python.org/3.4/library/pathlib.html
Bien qu'il soit répondu à cette question il y a longtemps. Je veux recommander d'utiliser le pathlib
module car c'est un moyen robuste de travailler sur Windows et Unix OS.
Donc, pour obtenir tous les chemins dans un répertoire spécifique, y compris les sous-répertoires:
from pathlib import Path
paths = list(Path('myhomefolder', 'folder').glob('**/*.txt'))
# all sorts of operations
file = paths[0]
file.name
file.stem
file.parent
file.suffix
etc.
Merci du conseil les gars. J'ai rencontré un problème avec les liens logiciels (récursion infinie) renvoyés sous forme de répertoires. Liens souples? Nous ne voulons pas de liens mous puants! Donc...
Cela n'a rendu que les répertoires, pas les liens logiciels:
>>> import os
>>> inf = os.walk('.')
>>> [x[0] for x in inf]
['.', './iamadir']
[x[0] for x in inf]
s'appelle- t-on en python pour que je puisse le rechercher?
Copier coller convivial dans ipython
:
import os
d='.'
folders = list(filter(lambda x: os.path.isdir(os.path.join(d, x)), os.listdir(d)))
Sortie de print(folders)
:
['folderA', 'folderB']
x
est l'élément de la liste créé par os.listdir(d)
car listdir
retournera les fichiers et dossiers avec lesquels il utilise la filter
commande os.path.isdir
pour filtrer tous les fichiers de la liste.
Voilà comment je le fais.
import os
for x in os.listdir(os.getcwd()):
if os.path.isdir(x):
print(x)
Voici quelques fonctions simples basées sur l'exemple de @Blair Conrad -
import os
def get_subdirs(dir):
"Get a list of immediate subdirectories"
return next(os.walk(dir))[1]
def get_subfiles(dir):
"Get a list of immediate subfiles"
return next(os.walk(dir))[2]
En s'appuyant sur la solution d'Eli Bendersky, utilisez l'exemple suivant:
import os
test_directory = <your_directory>
for child in os.listdir(test_directory):
test_path = os.path.join(test_directory, child)
if os.path.isdir(test_path):
print test_path
# Do stuff to the directory "test_path"
où <your_directory>
est le chemin d'accès au répertoire que vous souhaitez parcourir.
Cette réponse ne semblait pas déjà exister.
directories = [ x for x in os.listdir('.') if os.path.isdir(x) ]
J'ai eu une question similaire récemment, et j'ai découvert que la meilleure réponse pour python 3.6 (comme l'ajout d'un havlock utilisateur) est d'utiliser os.scandir
. Puisqu'il semble qu'il n'y ait pas de solution en l'utilisant, j'ajouterai la mienne. Tout d'abord, une solution non récursive qui répertorie uniquement les sous-répertoires directement sous le répertoire racine.
def get_dirlist(rootdir):
dirlist = []
with os.scandir(rootdir) as rit:
for entry in rit:
if not entry.name.startswith('.') and entry.is_dir():
dirlist.append(entry.path)
dirlist.sort() # Optional, in case you want sorted directory names
return dirlist
La version récursive ressemblerait à ceci:
def get_dirlist(rootdir):
dirlist = []
with os.scandir(rootdir) as rit:
for entry in rit:
if not entry.name.startswith('.') and entry.is_dir():
dirlist.append(entry.path)
dirlist += get_dirlist(entry.path)
dirlist.sort() # Optional, in case you want sorted directory names
return dirlist
gardez à l'esprit que vous entry.path
utilisez le chemin absolu vers le sous-répertoire. Si vous n'avez besoin que du nom du dossier, vous pouvez utiliser à la entry.name
place. Reportez-vous à os.DirEntry pour plus de détails sur l' entry
objet.
utiliser une fonction de filtre os.path.isdir
sur os.listdir()
quelque chose comme çafilter(os.path.isdir,[os.path.join(os.path.abspath('PATH'),p) for p in os.listdir('PATH/')])
Cela répertoriera tous les sous-répertoires dans l'arborescence des fichiers.
import pathlib
def list_dir(dir):
path = pathlib.Path(dir)
dir = []
try:
for item in path.iterdir():
if item.is_dir():
dir.append(item)
dir = dir + list_dir(item)
return dir
except FileNotFoundError:
print('Invalid directory')
pathlib
est nouveau dans la version 3.4
Fonction pour renvoyer une liste de tous les sous-répertoires d'un chemin de fichier donné. Recherche dans toute l'arborescence des fichiers.
import os
def get_sub_directory_paths(start_directory, sub_directories):
"""
This method iterates through all subdirectory paths of a given
directory to collect all directory paths.
:param start_directory: The starting directory path.
:param sub_directories: A List that all subdirectory paths will be
stored to.
:return: A List of all sub-directory paths.
"""
for item in os.listdir(start_directory):
full_path = os.path.join(start_directory, item)
if os.path.isdir(full_path):
sub_directories.append(full_path)
# Recursive call to search through all subdirectories.
get_sub_directory_paths(full_path, sub_directories)
return sub_directories
nous pouvons obtenir la liste de tous les dossiers en utilisant os.walk ()
import os
path = os.getcwd()
pathObject = os.walk(path)
ce pathObject est un objet et nous pouvons obtenir un tableau par
arr = [x for x in pathObject]
arr is of type [('current directory', [array of folder in current directory], [files in current directory]),('subdirectory', [array of folder in subdirectory], [files in subdirectory]) ....]
Nous pouvons obtenir la liste de tous les sous-répertoires en parcourant l' arr et en imprimant le tableau du milieu
for i in arr:
for j in i[1]:
print(j)
Cela imprimera tout le sous-répertoire.
Pour obtenir tous les fichiers:
for i in arr:
for j in i[2]:
print(i[0] + "/" + j)
Cette fonction, avec un parent donné, directory
itère sur tous ses éléments directories
récursifs et prints
tout filenames
ce qu'elle trouve à l'intérieur. Trop utile.
import os
def printDirectoryFiles(directory):
for filename in os.listdir(directory):
full_path=os.path.join(directory, filename)
if not os.path.isdir(full_path):
print( full_path + "\n")
def checkFolders(directory):
dir_list = next(os.walk(directory))[1]
#print(dir_list)
for dir in dir_list:
print(dir)
checkFolders(directory +"/"+ dir)
printDirectoryFiles(directory)
main_dir="C:/Users/S0082448/Desktop/carpeta1"
checkFolders(main_dir)
input("Press enter to exit ;")