views:

3196

answers:

5

How do i limit os.walk to only return files in the directory i provide it?

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
+1  A: 

You could use os.listdir() which returns a list of names (for both files and directories) in a given directory. If you need to distinguish between files and directories, call os.stat() on each name.

Greg Hewgill
+13  A: 

Don't use os.walk.

Example:

import os

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

The suggestion to use listdir is a good one. The direct answer to your question is root, dirs, files = os.walk(dir_name).next()

fivebells
Oh i was getting all sort of funny error from that one.ValueError: too many values to unpack
Setori
+1  A: 

If you have more complex requirements than just the top directory (eg ignore VCS dirs etc), you can also modify the list of directories to prevent os.walk recursting through them.

ie:

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

Note - be careful to mutate the list, rather than just rebind it. Obviously os.walk doesn't know about the external rebinding.

Brian
+4  A: 

Use the walklevel function.

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[:]

It works just like os.walk, but you can pass it a level parameter that indicates how deep the recursion will go.

nosklo
Does this function actually "walk" through the whole structure and then delete the entries below a certain point? Or is something more clever going on? I'm not even sure how to check this with code. --python beginner
mathtick
@mathtick: when some directory on or below the desired level is found, all of its subdirs are removed from the list of subdirs to search next. So they won't be "walked".
nosklo