Gibt es eine Möglichkeit, eine Liste aller Unterverzeichnisse im aktuellen Verzeichnis in Python zurückzugeben?
Ich weiß, dass man das mit Dateien machen kann, aber ich muss stattdessen die Liste der Verzeichnisse bekommen.
Gibt es eine Möglichkeit, eine Liste aller Unterverzeichnisse im aktuellen Verzeichnis in Python zurückzugeben?
Ich weiß, dass man das mit Dateien machen kann, aber ich muss stattdessen die Liste der Verzeichnisse bekommen.
Meinen Sie unmittelbare Unterverzeichnisse oder jedes Verzeichnis ganz unten im Baum?
So oder so, Sie können Folgendes verwenden os.walk
um dies zu tun:
os.walk(directory)
ergibt ein Tupel für jedes Unterverzeichnis. Der erste Eintrag in dem 3-Tupel ist ein Verzeichnisname, also
[x[0] for x in os.walk(directory)]
sollte Ihnen rekursiv alle Unterverzeichnisse anzeigen.
Beachten Sie, dass der zweite Eintrag im Tupel die Liste der untergeordneten Verzeichnisse des Eintrags an der ersten Position ist, so dass Sie dies stattdessen verwenden könnten, aber es ist nicht wahrscheinlich, dass Sie viel sparen.
Sie können aber auch nur die unmittelbaren Unterverzeichnisse angeben:
next(os.walk('.'))[1]
Oder sehen Sie sich die anderen bereits veröffentlichten Lösungen an, indem Sie os.listdir
y os.path.isdir
, einschließlich derjenigen unter " Wie man alle unmittelbaren Unterverzeichnisse in Python erhält ".
Viel schöner als das obige, weil Sie nicht mehrere os.path.join() brauchen und Sie direkt den vollständigen Pfad erhalten (wenn Sie wollen), können Sie dies tun in Python 3.5 und darüber.
subfolders = [ f.path for f in os.scandir(folder) if f.is_dir() ]
Dadurch wird der vollständige Pfad zum Unterverzeichnis angegeben. Wenn Sie nur den Namen des Unterverzeichnisses wollen, verwenden Sie f.name
anstelle von f.path
https://docs.python.org/3/library/os.html#os.scandir
Leicht OT: Falls Sie etwas brauchen alle Unterordner rekursiv und/oder alle Dateien rekursiv sehen Sie sich diese Funktion an, die schneller ist als os.walk
& glob
und gibt eine Liste aller Unterordner sowie aller Dateien innerhalb dieser (Unter-)Unterordner zurück: https://stackoverflow.com/a/59803793/2441026
Falls Sie nur alle Unterordner rekursiv :
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
Gibt eine Liste aller Unterordner mit ihren vollständigen Pfaden zurück. Dies ist wiederum schneller als os.walk
und viel schneller als glob
.
Eine Analyse aller Funktionen
tl;dr:
- Wenn Sie alles bekommen möchten sofort Unterverzeichnisse für einen Ordner verwenden os.scandir
.
- Wenn Sie sich alle Unterverzeichnisse, auch verschachtelt die, verwenden os.walk
oder - etwas schneller - die fast_scandir
Funktion oben.
- Verwenden Sie niemals os.walk
nur für Unterverzeichnisse der obersten Ebene, da es hunderte(!) Mal langsamer sein kann als os.scandir
.
os.walk
wird der Basisordner sein. Sie werden also nicht nur Unterverzeichnisse erhalten. Sie können verwenden fu.pop(0)
um sie zu entfernen.Ergebnisse :
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
Getestet mit 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()
Python 3.4 eingeführt el pathlib
Modul in die Standardbibliothek aufgenommen, die einen objektorientierten Ansatz zur Behandlung von Dateisystempfaden bietet:
from pathlib import Path
p = Path('./')
# All subdirectories in the current directory, not recursive.
[f for f in p.iterdir() if f.is_dir()]
Um alle Unterverzeichnisse rekursiv aufzulisten, Pfad-Globbing kann mit der Option **
Muster.
# This will also include the current directory '.'
list(p.glob('**'))
Beachten Sie, dass eine einzelne *
da das glob-Muster sowohl Dateien als auch Verzeichnisse nicht rekursiv einschließen würde. Um nur Verzeichnisse zu erhalten, muss ein nachgestellter /
kann angehängt werden, aber das funktioniert nur, wenn die glob-Bibliothek direkt verwendet wird, nicht wenn glob über pathlib verwendet wird:
import glob
# These three lines return both files and directories
list(p.glob('*'))
list(p.glob('*/'))
glob.glob('*')
# Whereas this returns only directories
glob.glob('*/')
Also Path('./').glob('**')
entspricht denselben Pfaden wie glob.glob('**/', recursive=True)
.
Pathlib ist auch unter Python 2.7 verfügbar über das Modul pathlib2 auf PyPi.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.