os.walk没有深入到下面的目录

时间:2008-10-23 10:03:59

标签: python file 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

21 个答案:

答案 0 :(得分:184)

不要使用os.walk。

示例:

import os

root = "C:\\"
for item in os.listdir(root):
    if os.path.isfile(os.path.join(root, item)):
        print item

答案 1 :(得分:89)

使用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 :(得分:38)

我认为解决方案实际上非常简单。

使用

break

只进行for循环的第一次迭代,必须有一种更优雅的方式。

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

第一次调用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")
        break
    return outputList

答案 3 :(得分:20)

使用listdir的建议很好。在Python 2中直接回答您的问题是root, dirs, files = os.walk(dir_name).next()

等效的Python 3语法是root, dirs, files = next(os.walk(dir_name))

答案 4 :(得分:10)

您可以使用os.listdir()返回给定目录中的名称列表(包括文件和目录)。如果您需要区分文件和目录,请在每个名称上调用os.stat()

答案 5 :(得分:9)

如果您的要求比顶级目录更复杂(例如忽略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不知道外部重新绑定。

答案 6 :(得分:4)

listdir相同的想法,但更短:

[f for f in os.listdir(root_dir) if os.path.isfile(os.path.join(root_dir, f))]

答案 7 :(得分:3)

感觉就像把我的2便士扔进去。

baselevel = len(rootdir.split("\\"))
for subdirs, dirs, files in os.walk(rootdir):
    curlevel = len(subdirs.split("\\"))
    if curlevel <= baselevel + 1:
        [do stuff]

答案 8 :(得分:3)

for path, dirs, files in os.walk('.'):
    print path, dirs, files
    del dirs[:] # go only one level deep

答案 9 :(得分:2)

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

答案 10 :(得分:1)

您还可以执行以下操作:

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

答案 11 :(得分:0)

使用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()的情况下更改到目录以进行测试。

答案 12 :(得分:0)

这就是我解决它的方式

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

...

答案 13 :(得分:0)

您可以使用此代码段

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

答案 14 :(得分:0)

创建一个排除列表,使用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
            ....

与&#39;包括&#39;:

相同
if **any**(fnmatch.fnmatch(nf_root, pattern) for pattern in **includes**):

答案 15 :(得分:0)

为什么不简单地将rangeos.walkzip结合使用?不是最佳解决方案,但也可以。

例如这样的例子:

# your part before
for count, (root, dirs, files) in zip(range(0, 1), os.walk(dir_name)):
    # logic stuff
# your later part

在python 3上为我工作。

另外:break也更简单。 (看@Pieter的答案)

答案 16 :(得分:0)

Alex的回答略有变化,但使用__next__()

print(next(os.walk('d:/'))[2]) 要么    print(os.walk('d:/').__next__()[2])

在其他答案中提到的[2]file中的root, dirs, file

答案 17 :(得分:0)

Python 3.5 起,您可以使用os.scandir代替os.listdir。您将获得DirEntry对象的迭代器,而不是字符串。从文档中:

  

使用scandir()代替listdir()可以显着提高还需要文件类型或文件属性信息的代码的性能,因为如果操作系统在以下情况下提供DirEntry对象,则它们会公开此信息:扫描目录。所有DirEntry方法都可以执行系统调用,但是is_dir()is_file()通常只需要系统调用即可进行符号链接; DirEntry.stat()在Unix上始终需要系统调用,而在Windows上仅需要一个系统调用即可。

您可以通过DirEntry.name访问对象的名称,该名称等效于os.listdir的输出

答案 18 :(得分:0)

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

答案 19 :(得分:0)

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

答案 20 :(得分:0)

这是一个很好的python示例

def walk_with_depth(root_path, depth):
        if depth < 0:
            for root, dirs, files in os.walk(root_path):
                yield [root, dirs[:], files]

            return

        elif depth == 0:
            return

        base_depth = root_path.rstrip(os.path.sep).count(os.path.sep)
        for root, dirs, files in os.walk(root_path):
            yield [root, dirs[:], files]

            cur_depth = root.count(os.path.sep)
            
            if base_depth + depth <= cur_depth:
                del dirs[:]