关于文件夹:python os.walk到一定程度

python os.walk to certain level

本问题已经有最佳答案,请猛点这里访问。

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

1
2
3
4
5
6
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)

在"主"文件夹中有多个文件夹之前,这非常有效,因为它会返回一个长的、垃圾的文件列表,因为文件夹/文件管理不好。所以我最多只想上二级。例子:

1
2
3
4
5
6
7
8
9
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

我只知道如何从这个职位和这个职位上获得一个break和一个del dirs[:]

1
2
3
4
5
6
7
8
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.

但无论我如何寻找,我都不知道该如何深入两层。我可能只是不理解上面的其他帖子或者什么?我在想类似于del dirs[:2]的东西,但没有用。有人能指导我或向我解释如何做到这一点吗?


你可以这样做:

1
2
3
4
for root,dirs,files in os.walk(stuff):
    if root[len(stuff)+1:].count(os.sep)<2:
        for f in files:
            print(os.path.join(root,f))

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

它从root中删除了stuff和分离器,因此结果与stuff相对应。只需计算文件分隔符的数量,除非获得0或1个分隔符,否则不要输入条件。

当然,它仍然会扫描完整的文件结构,但是除非它非常深,否则就可以工作。

另一种解决方案是只使用具有最大递归级别的os.listdir递归(带有目录检查),但如果不需要的话,这有点棘手。因为这并不难,这里有一个实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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

注:os.listdiros.path.isfile执行2个stat调用,因此不是最佳调用。在python 3.5中,使用os.scandir可以避免这种双重调用。


您可以计算分隔符,如果是两个级别的深度,则删除dirs的内容,这样walk就不会再出现更深的深度:

1
2
3
4
5
6
7
8
9
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[:]

python文档说明了以下行为:

When topdown is True, the caller can modify the dirnames list in-place (perhaps using del or slice assignment), and walk() will only recurse into the subdirectories whose names remain in dirnames; this can be used to prune the search, impose a specific order of visiting, or even to inform walk() about directories the caller creates or renames before it resumes walk() again.

请注意,您需要考虑folders中存在的分隔符。例如,当y:\path1是walked时,根目录是y:\path,但您不希望停止递归。