Skip to content
Advertisement

Walking/iterating over a nested dictionary of arbitrary depth (the dictionary represents a directory tree)

Python newbie at time of writing.

This came up because I want a user to be able to select a group of files from within a directory (and also any subdirectory), and unfortunately Tkinter’s default ability for selecting multiple files in a file dialog is broken on Windows 7 (http://bugs.python.org/issue8010).

So I am attempting to represent a directory structure by an alternative method (still using Tkinter): constructing a facsimile of the directory structure, made of labeled and indented checkboxes (organized in a tree). So a directory like this:

SomeRootDirectory
    foo.txt
    bar.txt
    Stories
        Horror
            scary.txt
            Trash
                notscary.txt
        Cyberpunk
    Poems
        doyoureadme.txt

will look something like this (where # represents a checkbutton):

SomeRootDirectory
    # foo.txt
    # bar.txt
    Stories
        Horror
            # scary.txt
            Trash
                # notscary.txt
        Cyberpunk
    Poems
        # doyoureadme.txt

Building the original dictionary from the directory structure is easy using a certain recipe I found at ActiveState (see below), but I hit a wall when I try to iterate over the nicely nested dictionary I am left with.

Advertisement

Answer

This is a preliminary code. Go through it and tell me where you face problems.

Parents={-1:"Root"}
def add_dir(level, parent, index, k):
    print "Directory"
    print "Level=%d, Parent=%s, Index=%d, value=%s" % (level, Parents[parent], index, k)
def add_file(parent, index, k):
    print "File"
    print "Parent=%s, Index=%d, value=%s" %  (Parents[parent], index, k)
def f(level=0, parent=-1, index=0, di={}):
    for k in di:
        index +=1
        if di[k]:
            Parents[index]=k
            add_dir(level, parent, index, k)
            f(level+1, index, index, di[k])
        else:
            add_file(parent, index, k)

a={
    'SomeRootDirectory': {
        'foo.txt': None,
        'bar.txt': None,
        'Stories': {
            'Horror': {
                'scary.txt' : None,
                'Trash' : {
                    'notscary.txt' : None,
                    },
                },
            'Cyberpunk' : None
            },
        'Poems' : {
            'doyoureadme.txt' : None
        }
    }
}

f(di=a)
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement