Os.walk без копания в каталогах ниже
Как ограничить os.walk
только возврат файлов в каталог, который я ему предоставляю?
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
Ответы
Ответ 1
Используйте функцию walklevel
.
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[:]
Он работает так же, как os.walk
, но вы можете передать ему параметр level
, указывающий, насколько глубока рекурсия.
Ответ 2
Не используйте os.walk.
Пример:
import os
root = "C:\\"
for item in os.listdir(root):
if os.path.isfile(os.path.join(root, item)):
print item
Ответ 3
Я думаю, что решение на самом деле очень просто.
использовать
break
чтобы делать только первую итерацию цикла for, должен быть более элегантный способ.
for root, dirs, files in os.walk(dir_name):
for f in files:
...
...
break
...
При первом вызове os.walk он возвращает тюльпаны для текущего каталога, а затем в следующем цикле содержимое следующего каталога.
Возьмите оригинальный script и просто добавьте break.
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
Ответ 4
Предложение использовать listdir
является хорошим. Прямой ответ на ваш вопрос в Python 2 - root, dirs, files = os.walk(dir_name).next()
.
Эквивалентный синтаксис Python 3 - root, dirs, files = next(os.walk(dir_name))
Ответ 5
Вы можете использовать os.listdir()
, который возвращает список имен (для файлов и каталогов) в заданной директории. Если вам нужно различать файлы и каталоги, вызовите os.stat()
для каждого имени.
Ответ 6
Если у вас более сложные требования, чем только верхний каталог (например, игнорировать VCS dirs и т.д.), вы также можете изменить список каталогов, чтобы предотвратить их повторение через os.walk.
т
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()
Примечание. Будьте осторожны, чтобы мутировать список, а не просто перетаскивать его. Очевидно, os.walk не знает о внешнем восстановлении.
Ответ 7
Та же идея с listdir
, но короче:
[f for f in os.listdir(root_dir) if os.path.isfile(os.path.join(root_dir, f))]
Ответ 8
for path, dirs, files in os.walk('.'):
print path, dirs, files
del dirs[:] # go only one level deep
Ответ 9
Почувствовал, как бросает мой 2 пенс.
baselevel = len(rootdir.split("\\"))
for subdirs, dirs, files in os.walk(rootdir):
curlevel = len(subdirs.split("\\"))
if curlevel <= baselevel + 1:
[do stuff]
Ответ 10
В Python 3 я смог сделать это:
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] )
Ответ 11
Вы также можете сделать следующее:
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
Ответ 12
Начиная с Python 3.5 вы можете использовать os.scandir
вместо os.listdir
. Вместо строк вы получаете DirEntry
итератор объектов DirEntry
. Из документов:
Использование scandir()
вместо listdir()
может значительно повысить производительность кода, который также требует информацию о типе файла или атрибуте файла, поскольку объекты DirEntry
предоставляют эту информацию, если операционная система предоставляет ее при сканировании каталога. Все методы DirEntry
могут выполнять системный вызов, но для is_dir()
и is_file()
обычно требуется только системный вызов для символических ссылок; DirEntry.stat()
всегда требует системного вызова в Unix, но требует только один для символических ссылок в Windows.
Вы можете получить доступ к имени объекта через DirEntry.name
которое затем эквивалентно выводу os.listdir
Ответ 13
Вот как я его решил
if recursive:
items = os.walk(target_directory)
else:
items = [next(os.walk(target_directory))]
...
Ответ 14
При использовании listdir существует улов. Os.path.isdir(идентификатор) должен быть абсолютным путем. Чтобы выбрать подкаталоги:
for dirname in os.listdir(rootdir):
if os.path.isdir(os.path.join(rootdir, dirname)):
print("I got a subdirectory: %s" % dirname)
Альтернативой является переход в каталог для проведения тестирования без использования os.path.join().
Ответ 15
Вы можете использовать этот фрагмент
for root, dirs, files in os.walk(directory):
if level > 0:
# do some stuff
else:
break
level-=1
Ответ 16
создайте список исключений, используйте fnmatch, чтобы пропустить структуру каталогов и выполнить процесс
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
....
то же, что и для 'includes':
if **any**(fnmatch.fnmatch(nf_root, pattern) for pattern in **includes**):
Ответ 17
Почему бы просто не использовать range
и os.walk
сочетании с zip
? Это не лучшее решение, но будет работать тоже.
Например, вот так:
# your part before
for count, (root, dirs, files) in zip(range(0, 1), os.walk(dir_name)):
# logic stuff
# your later part
У меня работает на питоне 3.
Кроме того: break
проще, кстати. (Посмотрите на ответ от @Pieter)
Ответ 18
Небольшое изменение в ответе Алекса, но с использованием __next__()
:
print(next(os.walk('d:/'))[2])
или print(os.walk('d:/').__next__()[2])
с [2]
- file
в root, dirs, file
упомянутый в других ответах
Ответ 19
корневая папка изменяется для каждого каталога, который находит os.walk. Я решаю, что проверка, если корневой каталог ==
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
Ответ 20
import os
def listFiles(self, dir_name):
names = []
for root, directory, files in os.walk(dir_name):
if root == dir_name:
for name in files:
names.append(name)
return names