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