在 os.walk 中排除目录

我正在编写一个脚本,该脚本下降到一个目录树(使用 os.walk ()) ,然后访问匹配某个文件扩展名的每个文件。然而,由于我的工具将要使用的一些目录树也包含子目录,而这些子目录又包含无用的 很多内容(为了这个脚本的目的) ,我想我应该为用户添加一个选项来指定要从遍历中排除的目录列表。

这对于 os.walk ()来说很简单。毕竟,这取决于我是否真正想要访问 os.walk ()生成的相应文件/dirs,还是直接跳过它们。问题是,如果我有一个像这样的目录树:

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

我想排除 没用的东西和它的所有子目录,os.walk ()仍然会下降到 没用的东西的所有子目录(可能有成千上万个) ,不用说,这会大大减慢速度。在一个理想的世界中,我可以告诉 os.walk ()甚至不用再生产任何 没用的东西的孩子,但据我所知,没有办法这样做(是吗?).

有人有什么想法吗? 也许有第三方图书馆提供类似的东西?

78003 次浏览

修改 dirs 就位将删除 os.walk访问的(后续)文件和目录:

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

来自 help (os.walk) :

当 topdown 为 true 时,调用方可以就地修改目录列表 (例如,通过 del 或片赋值) ,并且 walk 只会递归到 名称保留在目录中的子目录; 这可用于 停止搜索。

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

(正确执行需要使用 list(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]