Jak ograniczyć os.walk
zwracanie plików tylko z katalogu, który go podam?
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()]
. W przypadku, gdy potrzebujesz tylko nazw plików, użyjf.name
zamiastf.path
. Jest to najszybsze rozwiązanie i znacznie szybsze niż jakiekolwiek innewalk
lublistdir
, zobacz stackoverflow.com/a/40347279/2441026 .Odpowiedzi:
Użyj
walklevel
funkcji.Działa tak samo
os.walk
, ale możesz przekazać mulevel
parametr, który wskazuje, jak głęboko zajdzie rekurencja.źródło
dirs = []
idirs = None
ale te nie działają.map(dirs.remove, dirs)
zadziałało, ale zostało wydrukowanych kilka niechcianych komunikatów „[Brak]”. Więc dlaczegodel dirs[:]
konkretnie?topdown=False
w os.walk. Zobacz czwarty akapit w dokumentach :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 = []
idirs = None
nie będą działać, ponieważ po prostu tworzą nowy niepowiązany obiekt i przypisują go do nazwydirs
. Oryginalny obiekt listy należy zmodyfikować lokalnie, a nie nazwędirs
.Nie używaj os.walk.
Przykład:
źródło
os.path.isfile
ios.path.isdir
pozwala odróżnić. Nie rozumiem, ponieważos.path.isfile
znajduje się w przykładowym kodzie od '08, a twój komentarz pochodzi z '16. To jest zdecydowanie lepsza odpowiedź, ponieważ nie zamierzasz chodzić po katalogu, ale go wymienić.walk
wyświetla oddzielne listy katalogów i plików..next()
) i jest znacznie bliższa Twojemu pomysłowi.os.scandir
funkcję, która umożliwia bardziej wyrafinowaną interakcję plik-lub-katalog-obiekt. Zobacz moją odpowiedź poniżejMyślę, że rozwiązanie jest w rzeczywistości bardzo proste.
posługiwać się
aby wykonać tylko pierwszą iterację pętli for, musi istnieć bardziej elegancki sposób.
Przy pierwszym wywołaniu os.walk zwraca on tulipany dla bieżącego katalogu, a następnie w następnej pętli wyświetla zawartość następnego katalogu.
Weź oryginalny skrypt i po prostu dodaj przerwę .
źródło
Sugestia użycia
listdir
jest dobra. Bezpośrednia odpowiedź na twoje pytanie w Pythonie 2 brzmiroot, dirs, files = os.walk(dir_name).next()
.Odpowiednia składnia Pythona 3 to
root, dirs, files = next(os.walk(dir_name))
źródło
root, dirs, files = os.walk(dir_name).next()
daje miAttributeError: 'generator' object has no attribute 'next'
root, dirs, files = next(os.walk(dir_name))
i wtedy zmienneroot, dirs, files
będą odpowiadały tylko zmiennym generatora nadir_name
poziomie.Możesz użyć,
os.listdir()
który zwraca listę nazw (zarówno plików, jak i katalogów) w podanym katalogu. Jeśli potrzebujesz rozróżnić pliki i katalogi, wywołajos.stat()
każdą nazwę.źródło
Jeśli masz bardziej złożone wymagania niż tylko główny katalog (np. Zignoruj katalogi VCS itp.), Możesz również zmodyfikować listę katalogów, aby zapobiec powtarzaniu się przez nie os.walk.
to znaczy:
Uwaga - uważaj, aby zmodyfikować listę, a nie tylko ją ponownie powiązać. Oczywiście os.walk nie wie o zewnętrznym rebindingu.
źródło
źródło
Ten sam pomysł
listdir
, ale krótszy:źródło
Czułem się jak wrzucenie moich 2 pensów.
źródło
W Pythonie 3 udało mi się to zrobić:
źródło
Od Pythona 3.5 możesz używać
os.scandir
zamiastos.listdir
. Zamiast łańcuchów otrzymujeszDirEntry
w zamian iterator obiektów. Z dokumentów:Możesz uzyskać dostęp do nazwy obiektu, za pośrednictwem
DirEntry.name
której jest odpowiednikiem danych wyjściowych poleceniaos.listdir
źródło
scandir()
, ponieważ jest o wiele szybszy niżlistdir()
. Zobacz testy porównawcze tutaj: stackoverflow.com/a/40347279/2441026 .Możesz też wykonać następujące czynności:
źródło
Tak to rozwiązałem
źródło
Podczas korzystania z listdir jest pewien haczyk. Os.path.isdir (identyfikator) musi być ścieżką bezwzględną. Aby wybrać podkatalogi, które robisz:
Alternatywą jest przejście do katalogu, aby wykonać test bez funkcji os.path.join ().
źródło
Możesz użyć tego fragmentu
źródło
utwórz listę wykluczeń, użyj fnmatch, aby pominąć strukturę katalogów i wykonać proces
to samo, co w przypadku „obejmuje”:
źródło
Dlaczego nie po prostu użyć
range
i wos.walk
połączeniu zzip
? To nie jest najlepsze rozwiązanie, ale też by działało.Na przykład w ten sposób:
U mnie działa na Pythonie 3.
Poza tym: A przy
break
okazji też jest prostszy. (Spójrz na odpowiedź od @Pieter)źródło
Niewielka zmiana w odpowiedzi Alexa, ale używając
__next__()
:print(next(os.walk('d:/'))[2])
lubprint(os.walk('d:/').__next__()[2])
z
[2]
byciafile
wroot, dirs, file
wspomniano w innych odpowiedziźródło
zmiany folderu głównego dla każdego katalogu znalezionego przez os.walk. Rozwiązuję to sprawdzanie, czy root == katalog
źródło
źródło