0

I want to use os.makedirs to create a directory structure. I tried using braceexpand, and it worked in part:

for x in list(braceexpand('/Users/admin/Desktop/{cat,dog,bird}/{thing1,thing2,thing3,thing4}')): os.makedirs(x,exist_ok=True)

But instead of manually creating directories named 'cat', 'dog' and 'bird', I want to automate the process by creating the structure from a list.

animals = [ 'cat', 'dog', 'bird']

This is because I sometimes want only the intermediate directory 'dog', and sometimes 'dog' and 'cat', and sometimes all three. It would therefore be nice to be able to create the directory structure based on whatever subset of animals the list contains.

I haven't been able to implement this (braceexpand'ing using a list) so far.

With help from the answers here (Brace expansion in python glob), I was able to create the directory structure I wanted using nested for-loops with the code below.

for x in ['/Users/admin/Desktop/{s}/{b}'.format(b=b,s=s) for b in ['thing1','thing2','thing3','thing4'] for s in ['cat', 'dog', 'bird']]: os.makedirs(x,exist_ok=True)

But I like the readability of braceexpand, so I was curious whether anyone knew how to do it with that – or whether it is something that can even be done.

Thanks!

abra
  • 153
  • 2
  • 10
  • It would! But this is a minimal example for illustration purposes. I want to create directories from a list whose contents I may not know. This is why I'd like to automate the process by creating the directory structure from the list itself – and not by manually typing 'cat', 'dog', and 'bird'. I will edit my question to clarify. – abra Dec 09 '19 at 14:40

1 Answers1

0

You should be able to "hack" it using Python string interpolation before passing the string to braceexpand:

names = ['dog', 'cat', 'bird']    
print('/Users/admin/Desktop/{{{}}}/{{thing1,thing2,thing3,thing4}}'.format(','.join(names)))

Outputs

/Users/admin/Desktop/{dog,cat,bird}/{thing1,thing2,thing3,thing4}

Of course the same can be done for thing1,thing2,...

For an explanation why {{{}}} and {{ ... }} is needed, see this answer.

DeepSpace
  • 78,697
  • 11
  • 109
  • 154
  • Works! This isn't as intuitive as I was hoping braceexpand would be, but it's more concise than the for-loop approach, which is already helpful. Could you please explain how the bracketing works? – abra Dec 09 '19 at 15:41
  • @abra I added a link with an explanation. Simply put, the double braces just escape the braces which `str.format` normally uses for replacement – DeepSpace Dec 09 '19 at 15:54