tags:

views:

54

answers:

2

Follow up of my previous question: http://stackoverflow.com/questions/3680464/python-how-to-recursively-add-a-folders-content-in-a-dict.

When I build the information dict for each file and folder, I need to merge it to the main tree dict. The only way I have found so far is the write the dict as a text string and have it interpreted into a dict object and then merge it. The issue is that the root object is always the same so it gets overwritten by the new dict and I lose the content.

def recurseItem(Files, Item):
    global Settings
    ROOT = Settings['path']
    dbg(70, "Scanning " + Item)
    indices = path2indice(Item)
    ItemAnalysis = Analyse(Item)
    Treedict = ""#{'" + ROOT + "': "
    i=0
    for indice in indices:
        Treedict = Treedict + "{'" + indice + "': "
        i=i+1
    Treedict = Treedict + repr(ItemAnalysis)
    while i>0:
        Treedict = Treedict + "}"
        i=i-1
    Files = dict(Files.items() + Treedict.items())
return Files

Is there a way to avoid the messy indices construct (i.e. Files[ROOT][fileName][fileName2][fileName3][fileName4] ) which can't be generated on the fly? I need to be able to update a key's content without overwriting the root key. Any idea would be much welcomed !

A: 

I'm not entirely sure I understand what you're asking for, but it seems like a textbook case for recursion. I think something like this might be of use (as a replacement for your current method):

import os

FILES = ...
def process(directory):
    dir_dict = {}
    for file in os.listdir(directory):
        filename = os.path.join(directory, file)
        if os.path.isdir(file):
            dir_dict[file] = process(filename)
        else: # assuming it needs to be processed as a file
            dir_dict[file] = Analyse(filename)
    return dir_dict

(based on phihag's answer to your other question) Basically this constructs a dict for each directory containing the analyzed information about the files in that directory, and inserts that dict into the dict for the parent directory.

If it's not this, I think dict.update and/or the collections.defaultdict class may need to be involved.

David Zaslavsky
+1  A: 

Of course you can create nested dictionaries on-the-fly. What about this:

# Example path, I guess something like this is produced by path2indice?!
indices = ("home", "username", "Desktop")

tree = {}

d = tree
for indice in indices[:-1]:
    if indice not in d:
        d[indice] = {}

    d = d[indice]

d[indices[-1]] = "some value"

print tree # this will print {'home': {'username': {'Desktop': 'some value'}}}
AndiDog
This is exactly what I was looking for, thanks a lot
Daniel Gagnon
I am unsure why this works. Is this because when fed a tupple, the dict constructor recognizes a multi-dimensional construct and builds it as such ?
Daniel Gagnon
@Daniel Gagnon: There's no such thing like a multi-dimensional dict in Python. You can only have a dict as a value in another dict, and that's what my code does. As you can see, the `d` variable first points to the tree, then to the subtree, then to the subsubtree and so on. The loop creates the nested dictionary construct, and the final statement `d[indices[-1]] = "some value"` inserts the actual value at the end (instead of creating another subtree). Use print statements in the loop if you don't understand it!
AndiDog
Thanks for the anwser, much apreciated.
Daniel Gagnon
@Daniel if you like the answer, you should click the ✓ to accept it.
poolie
oups. Just did. Thanks for letting me know
Daniel Gagnon