在os.walk中排除目录

时间:2013-11-08 13:06:32

标签: python

我正在编写一个下载到目录树中的脚本(使用os.walk()),然后访问与特定文件扩展名匹配的每个文件。但是,由于我的工具将使用的一些目录树也包含子目录,而这些子目录又包含 LOT 无用(为了这个脚本的目的)的东西,我认为我' d为用户添加一个选项,以指定要从遍历中排除的目录列表。

使用os.walk()这很容易。毕竟,由我来决定我是否真的想要访问os.walk()产生的相应文件/目录,或者只是跳过它们。问题是,如果我有一个像这样的目录树:

root--
     |
     --- dirA
     |
     --- dirB
     |
     --- uselessStuff --
                       |
                       --- moreJunk
                       |
                       --- yetMoreJunk

我希望排除 uselessStuff 及其所有子项,os.walk()仍然会进入 uselessStuff 的所有(可能是数千个)子目录,不用说,减缓了很多事情。在一个理想的世界里,我可以告诉os.walk()甚至不打扰让 uselessStuff 更多的孩子,但据我所知,没有办法做到这一点(是吗?)。

有没有人有想法?也许有第三方库提供类似的东西?

2 个答案:

答案 0 :(得分:195)

修改dirs 就地将修剪os.walk访问过的(后续)文件和目录:

# exclude = set([...])
for root, dirs, files in os.walk(top, topdown=True):
    dirs[:] = [d for d in dirs if d not in exclude]

来自帮助(os.walk):

  

当topdown为true时,调用者可以就地修改dirnames列表   (例如,通过del或slice赋值),walk将只递归到   名称保留在dirnames中的子目录;这可以用来   修剪搜索...

答案 1 :(得分:5)

... @ unutbu的另一种形式的优秀答案,直接读取更多,因为意图是排除目录,代价为O(n ** 2)vs O (n)时间。

(正确执行需要使用list(dirs)制作dirs列表的副本)

# exclude = set([...])
for root, dirs, files in os.walk(top, topdown=True):
    [dirs.remove(d) for d in list(dirs) if d in exclude]