Brian B
Brian B

Reputation: 45

Python walker that does NOT go into specific folders

this is my first post, so be gentle. ;)

PROBLEM: I would like to be able to use os.walk as a directory walker, but not do into certain folders. Ex:

Tree:

\Proj1_0
    \Load001
        \lib
        \src
\Proj2_0
    \Load001
        \lib
        \src
    \Load002
        \lib
        \src

I want to show the projects and loads, but not the sub-directories under loads. I can do that using the following code.

import os


for root, subFolders, files in os.walk('.'):
    # root does NOT contain 'Load'
    if root.find('Load') == -1:
        print "\nPROJECT: " + root + "\n"
        for folder in subFolders:
            print "    " + folder

However, the list is a big list, so I tried using del to but could not get it to work right and the same thing using lists, such as (which I got from another post here):

def my_walk(top_dir, ignore):
    for dirpath, dirnames, filenames in os.walk(top_dir):
        dirnames[:] = [
            dn for dn in dirnames
            if os.path.join(dirpath, dn) not in ignore]
        yield dirpath, dirnames, filename
list my_walk('.','Load')

But I could not get the return to work properly, either. I am new to Python and appreciate any help. Thanks!

Upvotes: 2

Views: 207

Answers (3)

Brian B
Brian B

Reputation: 45

BTW, this is what I ended up with...

import os,string
path = '.'
path = os.path.normpath(path)
res = []

for root,dirs,files in os.walk(path, topdown=True):
    depth = root[len(path) + len(os.path.sep):].count(os.path.sep)
    if depth == 2:
        # We're currently two directories in, so all subdirs have depth 3
        res += [os.path.join(root, d) for d in dirs]
        dirs[:] = [] # Don't recurse any deeper
print(res)

I know this is an old post, but thought I should update it with my answer. In case, anyone else finds it useful.

Upvotes: 0

unutbu
unutbu

Reputation: 879571

Try:

    dirnames[:] = [
        dn for dn in dirnames
        if ignore not in os.path.join(dirpath, dn)]

You want to keep directories where os.path.join(dirpath, dn) does not contain the string ignore.


By the way, you are right to use dirnames[:] on the left-hand side of the assignment. To prune the directories visited by os.walk, you have to modify the same list dirnames.

dirnames[:] = ... modifies the same list in-place. dirnames = ... would redirect the name dirnames to a different value.

Upvotes: 2

rodrigo
rodrigo

Reputation: 98368

You can try the following:

for x in os.walk('.', topdown=True):
    dirpath, dirnames, dirfiles = x
    print(dirpath, dirnames)
    dirnames[:] = filter(lambda x : not x.startswith('Load'), dirnames)

From help(os.walk), you can modify the names if topdown is True, in order to restrict the search.

Upvotes: 1

Related Questions