Wie kann ich os.walk
so einschränken, dass nur Dateien in dem von mir angegebenen Verzeichnis zurückgegeben werden?
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
Verwenden Sie die walklevel
-Funktion.
import os
def walklevel(some_dir, level=1):
some_dir = some_dir.rstrip(os.path.sep)
assert os.path.isdir(some_dir)
num_sep = some_dir.count(os.path.sep)
for root, dirs, files in os.walk(some_dir):
yield root, dirs, files
num_sep_this = root.count(os.path.sep)
if num_sep + level <= num_sep_this:
del dirs[:]
Es funktioniert genauso wie os.walk
, aber Sie können einen level
-Parameter übergeben, der angibt, wie tief die Rekursion sein wird.
Verwenden Sie nicht os.walk.
Beispiel:
import os
root = "C:\\"
for item in os.listdir(root):
if os.path.isfile(os.path.join(root, item)):
print item
Ich denke, die Lösung ist eigentlich sehr einfach.
benutzen
break
um nur die erste Iteration der for-Schleife durchzuführen, muss es einen eleganteren Weg geben.
for root, dirs, files in os.walk(dir_name):
for f in files:
...
...
break
...
Wenn Sie os.walk zum ersten Mal aufrufen, werden Tulpen für das aktuelle Verzeichnis und dann in der nächsten Schleife der Inhalt des nächsten Verzeichnisses zurückgegeben.
Nehmen Sie das Original-Skript und fügen Sie einfach ein break hinzu.
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")
break
return outputList
Der Vorschlag zur Verwendung von listdir
ist gut. Die direkte Antwort auf Ihre Frage in Python 2 lautet root, dirs, files = os.walk(dir_name).next()
.
Die äquivalente Python 3-Syntax lautet root, dirs, files = next(os.walk(dir_name))
Sie könnten os.listdir()
verwenden, um eine Liste mit Namen (für Dateien und Verzeichnisse) in einem bestimmten Verzeichnis zurückzugeben. Wenn Sie zwischen Dateien und Verzeichnissen unterscheiden müssen, rufen Sie für jeden Namen os.stat()
auf.
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 durch sie rekursiert.
dh:
def _dir_list(self, dir_name, whitelist):
outputList = []
for root, dirs, files in os.walk(dir_name):
dirs[:] = [d for d in dirs if is_good(d)]
for f in files:
do_stuff()
Hinweis - Achten Sie darauf, die Liste zu mutieren, anstatt sie nur neu zu binden. Offensichtlich weiß os.walk nichts von der externen Umbindung.
Dieselbe Idee mit listdir
, aber kürzer:
[f for f in os.listdir(root_dir) if os.path.isfile(os.path.join(root_dir, f))]
Ich hatte das Gefühl, meine 2 Pence zu werfen.
baselevel = len(rootdir.split("\\"))
for subdirs, dirs, files in os.walk(rootdir):
curlevel = len(subdirs.split("\\"))
if curlevel <= baselevel + 1:
[do stuff]
In Python 3 konnte ich Folgendes tun:
import os
dir = "/path/to/files/"
#List all files immediately under this folder:
print ( next( os.walk(dir) )[2] )
#List all folders immediately under this folder:
print ( next( os.walk(dir) )[1] )
for path, dirs, files in os.walk('.'):
print path, dirs, files
del dirs[:] # go only one level deep
Sie können auch Folgendes tun:
for path, subdirs, files in os.walk(dir_name):
for name in files:
if path == ".": #this will filter the files in the current directory
#code here
Seit Python 3.5 können Sie os.scandir
anstelle von os.listdir
verwenden . Anstelle von Strings erhalten Sie im Gegenzug einen Iterator von DirEntry
NAME _ Objekten. Aus den Dokumenten:
Die Verwendung von
scandir()
anstelle vonlistdir()
kann die Leistung von Code erheblich verbessern, der auch Dateityp- oder Dateiattributinformationen benötigt, daDirEntry
name__-Objekte diese Informationen verfügbar machen, wenn das Betriebssystem sie beim Scannen eines Verzeichnisses bereitstellt. AlleDirEntry
name__-Methoden können einen Systemaufruf ausführen, aberis_dir()
undis_file()
erfordern normalerweise nur einen Systemaufruf für symbolische Verknüpfungen.DirEntry.stat()
erfordert unter Unix immer einen Systemaufruf, unter Windows jedoch nur einen für symbolische Links.
Sie können über _DirEntry.name
_ auf den Namen des Objekts zugreifen, was dann der Ausgabe von _os.listdir
_ entspricht.
root ordner wechselt für jedes verzeichnis das os.walk findet. Ich löse diese Prüfung, wenn root == Verzeichnis
def _dir_list(self, dir_name, whitelist):
outputList = []
for root, dirs, files in os.walk(dir_name):
if root == dir_name: #This only meet parent folder
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
So habe ich es gelöst
if recursive:
items = os.walk(target_directory)
else:
items = [next(os.walk(target_directory))]
...
erstellen Sie eine Liste von Ausschlüssen, überspringen Sie die Verzeichnisstruktur mit fnmatch und führen Sie den Vorgang aus
excludes= ['a\*\b', 'c\d\e']
for root, directories, files in os.walk('Start_Folder'):
if not any(fnmatch.fnmatch(nf_root, pattern) for pattern in excludes):
for root, directories, files in os.walk(nf_root):
....
do the process
....
wie bei 'include':
if **any**(fnmatch.fnmatch(nf_root, pattern) for pattern in **includes**):
Eine kleine Änderung an Alex 'Antwort, aber mit __next__()
:
print(next(os.walk('d:/'))[2])
oder print(os.walk('d:/').__next__()[2])
mit dem [2]
als file
in root, dirs, file
in anderen Antworten erwähnt
Bei Verwendung von listdir gibt es einen Haken. Der os.path.isdir (Bezeichner) muss ein absoluter Pfad sein. Um Unterverzeichnisse auszuwählen, tun Sie Folgendes:
for dirname in os.listdir(rootdir):
if os.path.isdir(os.path.join(rootdir, dirname)):
print("I got a subdirectory: %s" % dirname)
Die Alternative ist, in das Verzeichnis zu wechseln, um das Testen ohne os.path.join () durchzuführen.
Sie können dieses Snippet verwenden
for root, dirs, files in os.walk(directory):
if level > 0:
# do some stuff
else:
break
level-=1
Warum verwenden Sie nicht einfach eine range
und os.walk
in Kombination mit der Zip
? Ist nicht die beste Lösung, würde aber auch funktionieren.
Zum Beispiel so:
# your part before
for count, (root, dirs, files) in Zip(range(0, 1), os.walk(dir_name)):
# logic stuff
# your later part
Funktioniert für mich auf Python 3.
Auch: Eine break
ist übrigens einfacher. (Sehen Sie sich die Antwort von @Pieter an)