it-swarm.com.de

os.walk, ohne in die folgenden Verzeichnisse zu graben

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
81
Setori

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.

87
nosklo

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
177
Yuval Adam

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
34
Pieter

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))

18
Alex Coventry

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.

10
Greg Hewgill

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.

9
Brian

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))]
4
Oleg Gryb

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]
3
Matt R

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] )
2
Jay Sheth
for path, dirs, files in os.walk('.'):
    print path, dirs, files
    del dirs[:] # go only one level deep
2
masterxilo

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
1
Diana G

Seit Python 3.5 können Sie os.scandir anstelle von os.listdir verwenden . Anstelle von Strings erhalten Sie im Gegenzug einen Iterator von DirEntryNAME _ Objekten. Aus den Dokumenten:

Die Verwendung von scandir() anstelle von listdir() kann die Leistung von Code erheblich verbessern, der auch Dateityp- oder Dateiattributinformationen benötigt, da DirEntryname__-Objekte diese Informationen verfügbar machen, wenn das Betriebssystem sie beim Scannen eines Verzeichnisses bereitstellt. Alle DirEntryname__-Methoden können einen Systemaufruf ausführen, aber is_dir() und is_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.

0
ascripter

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
0
Pedro J. Sola

So habe ich es gelöst

if recursive:
    items = os.walk(target_directory)
else:
    items = [next(os.walk(target_directory))]

...
0
Deifyed

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**):
0
Hamsavardhini

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

0
Oleg

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.

0
Kemin Zhou

Sie können dieses Snippet verwenden

for root, dirs, files in os.walk(directory):
    if level > 0:
        # do some stuff
    else:
        break
    level-=1
0

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)

0
PiMathCLanguage