Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 411
m_floer Avatar asked Oct 12 '11 10:10

m_floer


People also ask

Can dictionary be nested to any depth?

Dictionaries can be nested to any depth. Dictionaries are mutable. Items are accessed by their position in a dictionary. All the keys in a dictionary must be of the same type.

How do you loop a nested dictionary in Python?

Iterate over all values of a nested dictionary in python We can achieve all this in a simple manner using recursion. Using the function nested_dict_pair_iterator() we iterated over all the values of a dictionary of dictionaries and printed each pair including the parent keys.

What is a nested dictionary explain with an example?

Nested Dictionary: Nesting Dictionary means putting a dictionary inside another dictionary. Nesting is of great use as the kind of information we can model in programs is expanded greatly.

What is depth of dictionary in Python?

The default value of level should be 0 and not 1. A simple dict is returning 2 as depth which is not correct. Also for None and empty dicts, the depth should be 0 and not 1.


2 Answers

Here is a function that prints all your file names. It goes through all the keys in the dictionary, and if they map to things that are not dictionaries (in your case, the filename), we print out the name. Otherwise, we call the function on the dictionary that is mapped to.

def print_all_files(directory):

    for filename in directory.keys():
        if not isinstance(directory[filename], dict):
            print filename
        else:
            print_all_files(directory[filename])

So this code can be modified to do whatever you want, but it's just an example of how you can avoid fixing the depth through use of recursion.

The key thing to understand is that each time print_all_files gets called, it has no knowledge of how deep it is in the tree. It just looks at the files that are right there, and prints the names. If there are directores, it just runs itself on them.

like image 187
oadams Avatar answered Oct 22 '22 17:10

oadams


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)
like image 29
spicavigo Avatar answered Oct 22 '22 18:10

spicavigo