Wie beschränke ich mich darauf os.walk
, nur Dateien in dem von mir bereitgestellten Verzeichnis zurückzugeben?
def _dir_list(self, dir_name, whitelist):
outputList = []
for root, dirs, files in os.walk(dir_name):
for f in files:
if os.path.splitext(f)[1] in whitelist:
outputList.append(os.path.join(root, f))
else:
self._email_to_("ignore")
return outputList
files_with_full_path = [f.path for f in os.scandir(dir) if f.is_file()]
. Falls Sie nur die Dateinamen benötigen, verwenden Sief.name
stattf.path
. Dies ist die schnellste Lösung und viel schneller als jede anderewalk
oderlistdir
siehe stackoverflow.com/a/40347279/2441026 .Antworten:
Verwenden Sie die
walklevel
Funktion.Es funktioniert genauso wie
os.walk
, aber Sie können ihm einenlevel
Parameter übergeben, der angibt, wie tief die Rekursion gehen wird.quelle
dirs = []
unddirs = None
aber die funktionierten nicht.map(dirs.remove, dirs)
funktioniert, aber mit einigen unerwünschten '[Keine]' Nachrichten gedruckt. Warum alsodel dirs[:]
speziell?topdown=False
in os.walk nicht funktioniert . Siehe den 4. Absatz in den Dokumenten :Modifying dirnames when topdown is False has no effect on the behavior of the walk, because in bottom-up mode the directories in dirnames are generated before dirpath itself is generated.
dirs = []
unddirs = None
funktioniert nicht, weil sie nur ein neues, nicht verwandtes Objekt erstellen und dem Namen zuweisendirs
. Das ursprüngliche Listenobjekt muss direkt geändert werden, nicht der Namedirs
.Verwenden Sie os.walk nicht.
Beispiel:
quelle
os.path.isfile
undos.path.isdir
lässt Sie unterscheiden. Ich verstehe es nicht, daos.path.isfile
es seit '08 im Beispielcode steht und Ihr Kommentar von '16 stammt. Dies ist eindeutig die bessere Antwort, da Sie nicht beabsichtigen, ein Verzeichnis zu durchsuchen, sondern es aufzulisten.walk
Sie sofort die separaten Listen von Verzeichnissen und Dateien erhalten..next()
) und es ist viel näher an Ihrer Idee.os.scandir
Funktion, die eine komplexere Interaktion zwischen Datei oder Verzeichnisobjekt ermöglicht. Siehe meine Antwort untenIch denke, die Lösung ist eigentlich sehr einfach.
verwenden
Um nur die erste Iteration der for-Schleife durchzuführen, muss es einen eleganteren Weg geben.
Wenn Sie os.walk zum ersten Mal aufrufen, werden Tulpen für das aktuelle Verzeichnis zurückgegeben und in der nächsten Schleife der Inhalt des nächsten Verzeichnisses.
Nehmen Sie das Original-Skript und fügen Sie einfach eine Pause hinzu .
quelle
Der Vorschlag
listdir
ist gut. Die direkte Antwort auf Ihre Frage in Python 2 lautetroot, dirs, files = os.walk(dir_name).next()
.Die entsprechende Python 3-Syntax lautet
root, dirs, files = next(os.walk(dir_name))
quelle
root, dirs, files = os.walk(dir_name).next()
gibt mirAttributeError: 'generator' object has no attribute 'next'
root, dirs, files = next(os.walk(dir_name))
und dann entsprechen die Variablenroot, dirs, files
nur den Variablen des Generators auf derdir_name
Ebene.Sie können verwenden
os.listdir()
, um eine Liste von Namen (sowohl für Dateien als auch für Verzeichnisse) in einem bestimmten Verzeichnis zurückzugeben. Wenn Sie zwischen Dateien und Verzeichnissen unterscheiden müssen, rufen Sieos.stat()
jeden Namen auf.quelle
Wenn Sie komplexere Anforderungen als nur das oberste Verzeichnis haben (z. B. VCS-Verzeichnisse ignorieren usw.), können Sie auch die Liste der Verzeichnisse ändern, um zu verhindern, dass os.walk diese erneut durchläuft.
dh:
Hinweis - Achten Sie darauf, die Liste zu mutieren, anstatt sie nur erneut zu binden. Offensichtlich weiß os.walk nichts über die externe Rückbindung.
quelle
quelle
Die gleiche Idee mit
listdir
, aber kürzer:quelle
Ich hatte das Gefühl, meine 2 Pence hineinzuwerfen.
quelle
In Python 3 konnte ich Folgendes tun:
quelle
Seit Python 3.5 können Sie
os.scandir
anstelle von verwendenos.listdir
. Anstelle von Zeichenfolgen erhalten SieDirEntry
im Gegenzug einen Iterator von Objekten. Aus den Dokumenten:Sie können auf den Namen des Objekts zugreifen
DirEntry.name
, über den dann die Ausgabe von entsprichtos.listdir
quelle
scandir()
, da es eine ist viel schneller alslistdir()
. Siehe Benchmarks hier: stackoverflow.com/a/40347279/2441026 .Sie können auch Folgendes tun:
quelle
So habe ich es gelöst
quelle
Bei der Verwendung von listdir gibt es einen Haken. Der os.path.isdir (Bezeichner) muss ein absoluter Pfad sein. So wählen Sie Unterverzeichnisse aus:
Die Alternative besteht darin, in das Verzeichnis zu wechseln, um die Tests ohne os.path.join () durchzuführen.
quelle
Sie können dieses Snippet verwenden
quelle
Erstellen Sie eine Liste mit Ausschlüssen, überspringen Sie mit fnmatch die Verzeichnisstruktur und führen Sie den Vorgang aus
das gleiche wie für 'enthält':
quelle
Warum nicht einfach ein
range
undos.walk
kombiniert mit demzip
? Ist nicht die beste Lösung, würde aber auch funktionieren.Zum Beispiel so:
Funktioniert für mich auf Python 3.
Auch: A
break
ist übrigens auch einfacher. (Schauen Sie sich die Antwort von @Pieter an)quelle
Eine kleine Änderung an Alex 'Antwort, aber mit
__next__()
:print(next(os.walk('d:/'))[2])
oderprint(os.walk('d:/').__next__()[2])
mit dem
[2]
Wesen derfile
inroot, dirs, file
in anderen Antworten erwähntquelle
Änderungen am Stammordner für jedes Verzeichnis, das os.walk findet. Ich löse diese Überprüfung, ob root == Verzeichnis
quelle
quelle