alphanumeric
alphanumeric

Reputation: 19329

How to stop os.walk from walking all sub-directories down?

Using:

def simpleFunc(dirName):
    import os
    fileList=[]
    for dir, dirs, filenames in os.walk(dirName):
        for filename in filenames:
            filepath=dir+'/'+filename
            fileList.append(filepath)
    print fileList


simpleFunc(os.path.dirname('/entire/path/to/file.ext'))

The problem is that os.walk just doesn't stop at /entire/path/to/ directory level but goes all the way down to the lowest sub-directory it can find. So if there is /entire/path/to/subdir1/subdir2/subdir3 then in additional to /entire/path/to/ all three sub-directories will be searched: ./subdir1/, ././subdir2/, ./././subdir3/. Question: how to make sure the function stops at the directory level specified: /entire/path/to/ and doesn't go all the way down?

Upvotes: 1

Views: 1201

Answers (5)

opperman.eric
opperman.eric

Reputation: 417

You can tell os.walk which directory to use explicitly

def simpleFunc(dirName):
    import os

    # set the dir name in a var
    dirName = '/higher_lever_dir/'

    for dir, dirs, filenames in os.walk(dirName):

        # this line forces loop to look ONLY in the specified dir
        dirs[:] = [d for d in dirs if d in dirName]

        for filename in filenames:
            filepath=dir+'/'+filename
            fileList.append(filepath)
    print fileList


simpleFunc(os.path.dirname('/entire/path/to/file.ext'))

Setting dirs[:] = [d for d in dirs if d in dirName] will exclude files in subdirectories that may exist in /higher_level_dir/

Upvotes: 0

yatoxa
yatoxa

Reputation: 1

You need to take the only first item from the os.walk generator:

import os

root, _, files = next(os.walk('/entire/path/to'))

and then append root dir to each filename:

files = map(lambda f: os.path.join(root, f), files)

or just:

files = [os.path.join(root, f) for f in files]

Upvotes: 0

Addison
Addison

Reputation: 1075

Sounds like you should use os.listdir instead.

import os

my_path = '/entire/path/to/files/'
file_list = []
for filename in os.listdir(my_path):
  filepath = os.path.join(my_path, filename)
  if os.path.isfile(filepath):
    fileList.append(filepath)

Upvotes: 1

Jeff Tratner
Jeff Tratner

Reputation: 17076

Based on what you've written, if you just want to search the specified directory. It might be better to use os.listdir and then just filter on os.path.isfile, e.g., like this:

def simple_func(dirpath):
    paths = os.listdir(dirpath)
    # create absolute paths
    abs_paths = [os.path.join(dirpath, p) for p in paths]
    # filter for paths that are files
    file_list = [p for p in paths if os.path.isfile(p)]
    return file_list

That way you don't have to deal with stopping the recursion and it's pretty clear which files you want. You might want to profile to see whether the multiple isfile calls hurt anything.

Upvotes: 2

sundar nataraj
sundar nataraj

Reputation: 8692

from os import listdir
from os.path import isfile, join
path='/entire/path/to/'
files = [ join(path,f) for f in listdir(path) if isfile(join(path,f)) ]

files return ur files. no need to declare new filelist

Upvotes: 2

Related Questions