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
159345 次浏览

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

别用 Os.walk。

例如:

import os


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

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

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

如果您有比顶部目录更复杂的需求(例如忽略 VCS dirs 等) ,您还可以修改目录列表,以防止 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 不知道外部重新绑定。

使用 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参数,该参数指示递归的深度。

你也可以这样做:

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

我认为解决方法其实很简单。

使用

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

listdir也有同样的想法,但更简短:

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

我就是这么解决的

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


...

使用 listdir 时有一个问题。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 ()的情况下进行测试。

在 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] )
for path, dirs, files in os.walk('.'):
print path, dirs, files
del dirs[:] # go only one level deep

您可以使用这个代码片段

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

想把我的两便士扔进去。

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

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

与“包括”相同:

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

为什么不简单地使用 rangeos.walk结合 zip?不是最好的解决方案,但也会工作。

例如:

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

我在巨蟒3上工作。

另外: 顺便说一下,break也更简单。(看看@Pieter 的答案)

亚历克斯的回答稍有变化,但使用 __next__():

print(next(os.walk('d:/'))[2]) 或者 print(os.walk('d:/').__next__()[2])

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

由于 Python 3.5你可以使用 os.scandir而不是 os.listdir。返回的是 DirEntry对象的迭代器,而不是字符串。来自文件:

使用 scandir()而不是 listdir()可以显著提高同时需要文件类型或文件属性信息的代码的性能,因为如果操作系统在扫描目录时提供了这些信息,那么 DirEntry对象就会公开这些信息。所有的 DirEntry方法都可以执行一个系统调用,但是 is_dir()is_file()通常只需要一个符号链接的系统调用; DirEntry.stat()总是需要 Unix 上的一个系统调用,但是在 Windows 上只需要一个符号链接的系统调用。

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

解决这个问题的方法是检查 root = = 目录

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
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

这是一个很好的 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[:]