os.walk без копания в каталогах ниже - PullRequest
86 голосов
/ 23 октября 2008

Как ограничить 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

Ответы [ 19 ]

185 голосов
/ 23 октября 2008

Не используйте os.walk.

Пример:

import os

root = "C:\\"
for item in os.listdir(root):
    if os.path.isfile(os.path.join(root, item)):
        print item
92 голосов
/ 24 октября 2008

Используйте функцию 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, который указывает, насколько глубокой будет рекурсия.

38 голосов
/ 01 января 2014

Я думаю, что решение на самом деле очень простое.

использовать

break

чтобы сделать только первую итерацию цикла for, должен быть более элегантный способ.

for root, dirs, files in os.walk(dir_name):
    for f in files:
        ...
        ...
    break
...

При первом вызове os.walk он возвращает тюльпаны для текущего каталога, затем в следующем цикле содержимое следующего каталога.

Возьмите оригинальный скрипт и просто добавьте 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
20 голосов
/ 23 октября 2008

Рекомендуется использовать listdir. Прямой ответ на ваш вопрос в Python 2: root, dirs, files = os.walk(dir_name).next().

Эквивалентный синтаксис Python 3: root, dirs, files = next(os.walk(dir_name))

11 голосов
/ 23 октября 2008

Вы можете использовать os.listdir(), который возвращает список имен (как для файлов, так и для каталогов) в данном каталоге. Если вам необходимо различать файлы и каталоги, вызывайте os.stat() для каждого имени.

9 голосов
/ 23 октября 2008

Если у вас есть более сложные требования, чем просто верхний каталог (например, игнорируйте каталоги VCS и т. Д.), Вы также можете изменить список каталогов, чтобы предотвратить повторное прохождение через них 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 не знает о внешней привязке.

4 голосов
/ 26 июня 2014

Та же идея с listdir, но короче:

[f for f in os.listdir(root_dir) if os.path.isfile(os.path.join(root_dir, f))]
3 голосов
/ 02 июня 2017

Чувствовал, как бросил 2 пенса.

baselevel = len(rootdir.split("\\"))
for subdirs, dirs, files in os.walk(rootdir):
    curlevel = len(subdirs.split("\\"))
    if curlevel <= baselevel + 1:
        [do stuff]
3 голосов
/ 03 мая 2016
for path, dirs, files in os.walk('.'):
    print path, dirs, files
    del dirs[:] # go only one level deep
2 голосов
/ 01 апреля 2016

В 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] )
...