python os.walk到一定程度

Mat*_*ttR 10 python directory subdirectory python-os

我想构建一个程序,它使用一些基本代码来读取文件夹并告诉我文件夹中有多少文件.我目前是这样做的:

import os

folders = ['Y:\\path1', 'Y:\\path2', 'Y:\\path3']
for stuff in folders:
    for root, dirs, files in os.walk(stuff, topdown=True):
        print("there are", len(files), "files in", root)
Run Code Online (Sandbox Code Playgroud)

这很有效,直到"main"文件夹中有多个文件夹,因为文件夹/文件管理不佳,它可能会返回一个长的垃圾文件列表.所以我最多只想进入第二级.例:

Main Folder
---file_i_want
---file_i_want
---Sub_Folder
------file_i_want <--*
------file_i want <--*
------Sub_Folder_2
---------file_i_dont_want
---------file_i_dont_want
Run Code Online (Sandbox Code Playgroud)

我知道如何去只有第一层用break,用del dirs[:]取自这篇文章也是这个职位.

import os
import pandas as pd

folders = ['Y:\\path1', 'Y:\\path2', 'Y:\\path3']
for stuff in folders:
    for root, dirs, files in os.walk(stuff, topdown=True):
        print("there are", len(files), "files in", root)
        del dirs[:] # or a break here. does the same thing.
Run Code Online (Sandbox Code Playgroud)

但无论我的搜索,我都无法找到如何深入两层.我可能只是不了解其他帖子或其他什么?我在想什么,del dirs[:2]但无济于事.有人可以指导我或解释为什么要完成这个?

Jea*_*bre 13

你可以这样做:

depth = 2

# [1] abspath() already acts as normpath() to remove trailing os.sep
#, and we need ensures trailing os.sep not exists to make slicing accurate. 
# [2] abspath() also make /../ and ////, "." get resolved even though os.walk can returns it literally.
# [3] expanduser() expands ~
# [4] expandvars() expands $HOME
stuff = os.path.abspath(os.path.expanduser(os.path.expandvars(stuff)))

for root,dirs,files in os.walk(stuff):
    if root[len(stuff):].count(os.sep) < depth:
        for f in files:
            print(os.path.join(root,f))
Run Code Online (Sandbox Code Playgroud)

关键是: if root[len(stuff):].count(os.sep) < depth

stuff从中删除+分隔符root,因此结果是相对的stuff.只计算文件分隔符的数量,除非得到0或1个分隔符,否则不要输入条件.

当然,它仍会扫描完整的文件结构,但除非它非常深,否则会起作用.

另一种解决方案是仅使用find最大递归级别递归(使用目录检查),但如果您不需要它,则会有点棘手.既然不是那么难,这里有一个实现:

def scanrec(root):
    rval = []

    def do_scan(start_dir,output,depth=0):
        for f in os.listdir(start_dir):
            ff = os.path.join(start_dir,f)
            if os.path.isdir(ff):
                if depth<2:
                    do_scan(ff,output,depth+1)
            else:
                output.append(ff)

    do_scan(root,rval,0)
    return rval

print(scanrec(stuff))  # prints the list of files not below 2 deep
Run Code Online (Sandbox Code Playgroud)

注意:-maxdepth 0-maxdepth 1执行2次-maxdepth 2调用,因此不是最佳选择.在Python 3.5中,使用os.listdir可以避免双重调用.


nie*_*mmi 6

你可以指望的分隔符,如果它是两层深删除的内容dirs,以便walk不递归更深:

import os

MAX_DEPTH = 2
folders = ['Y:\\path1', 'Y:\\path2', 'Y:\\path3']
for stuff in folders:
    for root, dirs, files in os.walk(stuff, topdown=True):
        print("there are", len(files), "files in", root)
        if root.count(os.sep) - stuff.count(os.sep) == MAX_DEPTH - 1:
            del dirs[:]
Run Code Online (Sandbox Code Playgroud)

Python 文档说明了以下行为:

当 topdown 为 True 时,调用者可以就地修改 dirnames 列表(可能使用 del 或 slice 赋值),而 walk() 只会递归到名称保留在 dirnames 中的子目录;这可用于修剪搜索,施加特定的访问顺序,甚至在调用者再次恢复 walk() 之前通知 walk() 有关调用者创建或重命名的目录。

请注意,您需要考虑folders. 例如,当y:\path1根是什么时候,y:\path但你不想在那里停止递归。