3

I have a list of filenames and want to print them as a directory tree:

files = ["foo/bar/Bla", "foo/bar/Foo", "foo/foo/Bsdf", "xsd/sdafd/saasf"]
[...]
# output should look like this 
output = ['foo' : ['bar' : ['Bla', 'Foo'], 'foo' : ['Bsdf']], 'xsd' : ['sdafd' : ['saasf']]]

i tried different ways but i cannot get further than having something like this:

['foo/bar': ['Bla', 'Foo'], 'foo/foo/': ['Bsdf'], 'xsd/sdafd' : ['saasf']]

or similar...

reox
  • 5,036
  • 11
  • 53
  • 98
  • Are you defining your list of pathes yourself, or generating it dynamically ? if the latter is true, you should look at http://docs.python.org/2/library/os.path.html#os.path.walk – astrognocci Jul 16 '13 at 10:34

2 Answers2

1

This code works on your input:

def recurse_setdefault(res, array):
    if len(array) == 0:
        return
    elif len(array) == 1:
        res.append(array[0])
    else:
        recurse_setdefault(res.setdefault(array[0], [] if len(array) == 2 else {}), array[1:])

res = {}
for f in files:
    recurse_setdefault(res, f.split("/"))

The result is:

{'foo': {'bar': ['Bla', 'Foo'], 'foo': ['Bsdf']}, 'xsd': {'sdafd': ['saasf']}}
filmor
  • 30,840
  • 6
  • 50
  • 48
1

Couldn't get a one-liner

files = ["foo/bar/Bla", "foo/bar/Foo", "foo/foo/Bsdf", "xsd/sdafd/saasf"]

dict_add = lambda x, y={}: dict_add(x[:-1], y).setdefault(x[-1], {}) if(x) else y
base_dict = {}
map(lambda x: dict_add(x, base_dict), [path.split("/") for path in files])
dilbert
  • 3,008
  • 1
  • 25
  • 34