如何限制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
答案 0 :(得分:184)
不要使用os.walk。
示例:
import os
root = "C:\\"
for item in os.listdir(root):
if os.path.isfile(os.path.join(root, item)):
print item
答案 1 :(得分:89)
使用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
参数,指示递归的深度。
答案 2 :(得分:38)
我认为解决方案实际上非常简单。
使用
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
答案 3 :(得分:20)
使用listdir
的建议很好。在Python 2中直接回答您的问题是root, dirs, files = os.walk(dir_name).next()
。
等效的Python 3语法是root, dirs, files = next(os.walk(dir_name))
答案 4 :(得分:10)
您可以使用os.listdir()
返回给定目录中的名称列表(包括文件和目录)。如果您需要区分文件和目录,请在每个名称上调用os.stat()
。
答案 5 :(得分:9)
如果您的要求比顶级目录更复杂(例如忽略VCS目录等),您还可以修改目录列表以防止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不知道外部重新绑定。
答案 6 :(得分:4)
与listdir
相同的想法,但更短:
[f for f in os.listdir(root_dir) if os.path.isfile(os.path.join(root_dir, f))]
答案 7 :(得分:3)
感觉就像把我的2便士扔进去。
baselevel = len(rootdir.split("\\"))
for subdirs, dirs, files in os.walk(rootdir):
curlevel = len(subdirs.split("\\"))
if curlevel <= baselevel + 1:
[do stuff]
答案 8 :(得分:3)
for path, dirs, files in os.walk('.'):
print path, dirs, files
del dirs[:] # go only one level deep
答案 9 :(得分:2)
在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] )
答案 10 :(得分:1)
您还可以执行以下操作:
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
答案 11 :(得分:0)
使用listdir时有一个问题。 os.path.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()的情况下更改到目录以进行测试。
答案 12 :(得分:0)
这就是我解决它的方式
if recursive:
items = os.walk(target_directory)
else:
items = [next(os.walk(target_directory))]
...
答案 13 :(得分:0)
您可以使用此代码段
for root, dirs, files in os.walk(directory):
if level > 0:
# do some stuff
else:
break
level-=1
答案 14 :(得分:0)
创建一个排除列表,使用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
....
与&#39;包括&#39;:
相同if **any**(fnmatch.fnmatch(nf_root, pattern) for pattern in **includes**):
答案 15 :(得分:0)
为什么不简单地将range
和os.walk
与zip
结合使用?不是最佳解决方案,但也可以。
例如这样的例子:
# your part before
for count, (root, dirs, files) in zip(range(0, 1), os.walk(dir_name)):
# logic stuff
# your later part
在python 3上为我工作。
另外:break
也更简单。 (看@Pieter的答案)
答案 16 :(得分:0)
Alex的回答略有变化,但使用__next__()
:
print(next(os.walk('d:/'))[2])
要么
print(os.walk('d:/').__next__()[2])
在其他答案中提到的[2]
是file
中的root, dirs, file
答案 17 :(得分:0)
自 Python 3.5 起,您可以使用os.scandir
代替os.listdir
。您将获得DirEntry
对象的迭代器,而不是字符串。从文档中:
使用
scandir()
代替listdir()
可以显着提高还需要文件类型或文件属性信息的代码的性能,因为如果操作系统在以下情况下提供DirEntry
对象,则它们会公开此信息:扫描目录。所有DirEntry
方法都可以执行系统调用,但是is_dir()
和is_file()
通常只需要系统调用即可进行符号链接;DirEntry.stat()
在Unix上始终需要系统调用,而在Windows上仅需要一个系统调用即可。
您可以通过DirEntry.name
访问对象的名称,该名称等效于os.listdir
的输出
答案 18 :(得分:0)
根文件夹更改。我求解器检查根==目录
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
答案 19 :(得分:0)
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
答案 20 :(得分:0)
这是一个很好的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[:]