2008-10-23 71 views
70

如何限制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 
+0

其中,与他们一起去可能的方法,所有的告诫众人表明这种功能应该被加入到Python的另一种情况标准库。 – antred 2016-10-31 19:26:09

回答

74

使用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参数,指示递归将有多深。

+1

这个函数实际上是“遍历”整个结构,然后删除某个点下面的条目吗?或者是更聪明的事情呢?我甚至不知道如何用代码来检查。 --python beginner – mathtick 2010-08-19 18:05:48

6

你可以使用os.listdir()返回名称的列表(文件和目录)在指定目录。如果您需要区分文件和目录,请在每个名称上拨打os.stat()

154

请勿使用os.walk。

实施例:

import os 

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

这应该是被接受的答案... – 576i 2016-05-19 12:29:24

+1

@ 576i:这不区分文件和目录 – Olexandr 2016-06-03 09:07:29

+0

@Alexandr`os.path.isfile`和`os.path.isdir`让您区分。我不明白,因为`'os.path.isfile`在'08之后就是示例代码,而你的评论是'16'。这显然是更好的答案,因为你不打算走一个目录,而是要列出它。 – 2017-08-29 08:17:38

14

使用listdir的建议是一个好。你的问题的直接答案是root, dirs, files = os.walk(dir_name).next()

+0

哦,我从那一个得到各种有趣的错误。 ValueError:打开太多的值 – Setori 2008-10-24 01:34:27

+0

不错!虽然感觉像黑客。就像当你打开一个引擎,但只让它进行一次革命,然后拉出钥匙让它死亡。 – 2017-08-29 08:24:12

8

如果你有比顶级目录更复杂的要求(例如忽略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显然不知道外部重新绑定。

+1

指出需要改变dirs! – darKoram 2012-11-20 22:43:11

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 
22

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

使用

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 
4

listdir同样的想法,但更短:

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

这是我如何解决它

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

... 
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()。

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

您可以使用此代码段

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

感觉自己就像扔我的2便士

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

创建排除列表,使用fnmatch跳过目录结构和d执行过程

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**):