How to create directories and sub directories efficiently and elegantly in Python 2.7?

8.2k views Asked by At

I am trying to create a bunch of directories and sub directories at a specific location in my PC. My process is something like this:

  1. Check if there's any directory with the same directory name. Skip if so.
  2. If not, create the directory and the pre-defined sub directories under that directory.

This is the code I came up with using os module:

def Test():
    main_dir = ["FolderA", "FolderB"] 
    common_dir = ["SubFolder1", "SubFolder2", "SubFolder3"]

    for dir1 in main_dir:
        if not os.path.isdir(dir1):
            for dir2 in common_dir:
                os.makedirs("%s/%s" %(dir1,dir2))

I am wondering if there's any better way to do this very same task (probably shorter, more efficient and more pythonic)?

2

There are 2 answers

1
Martin Konecny On BEST ANSWER

Python follows the philosophy

It is better to ask for forgiveness than to ask for permission.

So rather than checking isdir, you would simply catch the exception thrown if the leaf directory already exists:

def Test():
    main_dir = ["FolderA", "FolderB"] 
    common_dir = ["SubFolder1", "SubFolder2", "SubFolder3"]

    for dir1 in main_dir:
        for dir2 in common_dir:
            try: os.makedirs(os.path.join(dir1,dir2))
            except OSError: pass

You can also replace string interpolation "%s/%s" %(dir1,dir2) with os.path.join(dir1, dir2)

Another more succinct way is to do the cartesian product instead of using two nested for-loops:

for dir1, dir2 in itertools.product(main_dir, common_dir):
    try: os.makedirs(os.path.join(dir1,dir2))
    except OSError: pass
0
James Mills On

How about:

import os
from itertools import starmap

def Test():
    main_dir = ["FolderA", "FolderB"] 
    common_dir = ["SubFolder1", "SubFolder2", "SubFolder3"]

    map(os.makedirs, starmap(os.path.join, zip(main_dir, common_dir)))

And if we're worried about os.makedirs() throwing errors:

import os
from itertools import starmap

def safe_makedirs(*args):
    try:
        return os.makedirs(*args)
    except:
        pass  # Ignore errors; for example if the paths already exist!

def Test():
    main_dir = ["FolderA", "FolderB"] 
    common_dir = ["SubFolder1", "SubFolder2", "SubFolder3"]

    map(safe_makedirs, starmap(os.path.join, zip(main_dir, common_dir)))