Nick
Nick

Reputation: 161

Check if a given directory contains any directory in python

Essentially, I'm wondering if the top answer given to this question can be implemented in Python. I am reviewing the modules os, os.path, and shutil and I haven't yet been able to find an easy equivalent, though I assume I'm just missing something simple.

More specifically, say I have a directory A, and inside directory A is any other directory. I can call os.walk('path/to/A') and check if dirnames is empty, but I don't want to make the program go through the entire tree rooted at A; i.e. what I'm looking for should stop and return true as soon as it finds a subdirectory.

For clarity, on a directory containing files but no directories an acceptable solution will return False.

Upvotes: 5

Views: 16561

Answers (4)

Joran Beasley
Joran Beasley

Reputation: 114098

maybe you want

def folders_in(path_to_parent):
    for fname in os.listdir(path_to_parent):
        if os.path.isdir(os.path.join(path_to_parent,fname)):
            yield os.path.join(path_to_parent,fname)

print(list(folders_in("/path/to/parent")))

this will return a list of all subdirectories ... if its empty then there are no subdirectories

or in one line

set([os.path.dirname(p) for p in glob.glob("/path/to/parent/*/*")])

although for a subdirectory to be counted with this method it must have some file in it

or manipulating walk

def subfolders(path_to_parent):
     try:
        return next(os.walk(path_to_parent))[1]
     except StopIteration:
        return []

 

Upvotes: 11

Flint Weather
Flint Weather

Reputation: 11

I apparently can't comment yet; however, I wanted to update part of the answer https://stackoverflow.com/users/541038/joran-beasley gave, or at least what worked for me.

Using python3 (3.7.3), I had to modify his first code snippet as follows:

import os

def has_folders(path_to_parent):
   for fname in os.listdir(path_to_parent):
     if os.path.isdir(os.path.join(path_to_parent, fname)):
       yield os.path.join(path_to_parent, fname)

print(list(has_folders("/repo/output")))

Further progress on narrowing to "does given directory contain any directory" results in code like:

import os

def folders_in(path_to_parent):
  for fname in os.listdir(path_to_parent):
    if os.path.isdir(os.path.join(path_to_parent, fname)):
      yield os.path.join(path_to_parent, fname)

def has_folders(path_to_parent):
  folders = list(folders_in(path_to_parent))
  return len(folders) != 0

print(has_folders("the/path/to/parent"))

The result of this code should be True or False

Upvotes: 0

dstromberg
dstromberg

Reputation: 7187

Try this:

#!/usr/local/cpython-3.4/bin/python

import glob
import os

top_of_hierarchy = '/tmp/'
#top_of_hierarchy = '/tmp/orbit-dstromberg'

pattern = os.path.join(top_of_hierarchy, '*')

for candidate in glob.glob(pattern):
    if os.path.isdir(candidate):
        print("{0} is a directory".format(candidate))
        break
else:
    print('No directories found')

# Tested on 2.6, 2.7 and 3.4

Upvotes: 1

Marcin
Marcin

Reputation: 238985

I would just do as follows:

#for example
dir_of_interest = "/tmp/a/b/c"

print(dir_of_interest in (v[0] for v in os.walk("/tmp/")))

This prints True or False, depending if dir_of_interest is in the generator. And you use here generator, so the directories to check are generated one by one.

You can break from the walk anytime you want. For example, this brakes is a current folder being walked, has no subdirectories:

for root, dirs, files in os.walk("/tmp/"):
    print(root,len(dirs))
    if not len(dirs): break

Maybe this is in line with what you are after.

Upvotes: 2

Related Questions