Marche/itération sur un imbriquée dictionnaire de profondeur arbitraire (le dictionnaire représente une arborescence de répertoires)

Je suis presque certain qu'il existe une solution simple à ce problème, mais j'ai passé des heures à lire et relire le même ensemble de résultats qui ne sont pas tout à fait répondre à mon problème.

Contexte de cette question (inclus pour la réalisation, mais n'hésitez pas à sauter cette)

C'est venu parce que je veux à un utilisateur d'être en mesure de sélectionner un groupe de fichiers dans un répertoire (et aussi les sous-répertoire), et, malheureusement, Tkinter, de la capacité par défaut pour la sélection de plusieurs fichiers dans une boîte de dialogue de fichier est cassé sur Windows 7 (http://bugs.python.org/issue8010).

Donc j'essaie de représenter une structure de répertoires par une méthode alternative (toujours en utilisant Tkinter): la construction d'un fac-similé de la structure de répertoire, fait de étiquetés et décalés des cases à cocher (organisés dans un arbre). Ainsi, un répertoire comme ceci:

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

va ressembler à quelque chose comme ceci (où # représente un checkbutton):

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

La construction du dictionnaire initial de la structure de répertoire est facile à l'aide d'un certain recette que j'ai trouvé à la ActiveState (voir ci-dessous), mais j'ai frappé un mur lorsque je tente d'effectuer une itération sur le bien imbriqués dictionnaire, je suis reparti avec. Et je pense que j'ai besoin pour effectuer une itération sur elle afin de remplir un Tkinter cadre avec une jolie maillées représentation de l'arbre. Alors j'espère charge dans les différents fichiers de texte sélectionné par l'utilisateur, par l'interprétation qui les cases étaient vraies ou fausses. Tout semble assez facile à l'exception de parcourir le dictionnaire sans la fixation de la profondeur.

En plus de termes abstraits

De faire de ces dictionnaires imbriqués, je suis en utilisant un ActiveState recette -- http://code.activestate.com/recipes/577879/. Il met en oeuvre des os.pied pour faire les dictionnaires comme ceci:

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

Après le point, je suis perplexe. Je suis un débutant en Python au moment de la rédaction

Solution adaptée à partir de spicavigo réponse

#distinguish between directory and file
dirtab = "/==="
filetab = "|---"

Parents={ -1:"Root"}
def add_dir(level, parent, index, k):
    print (dirtab*level)+k
def add_file(level, parent, index, k):
    #Currently an empty folder gets passed to add_file; here's a quick treatment.
    if "." in k:
        print (filetab*level)+k
    else:
        print (dirtab*level)+k
def addemup(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)
            addemup(level+1, index, index, di[k])
        else:
            add_file(level, parent, index, k)

addemup(di=a) #dictionary from above

Ce produit quelque chose qui je pense sera très facile de réviser dans un Tkinter représentation:

SomeRootDirectory
/===Poems
|--- | ---doyoureadme.txt
/===Stories
/===/===Horror
|--- | --- | ---rickscott.txt
/===/===/===Trash
|--- | --- | --- | ---notscary.txt
/===/===Cyberpunk
|---foo.txt
|---bar.txt

Grâce, cette communauté est incroyable.

lorsque vous parcourez le dictionnaire de paires clé-valeur (à l'intérieur d'une fonction qui prend dictionnaire comme argument), vous pouvez vérifier si la valeur est un type de dictionnaire, si oui, alors appelez votre fonction c'est à dire utiliser la récursivité ici et passer la valeur comme un dictionnaire à la fonction, d'autre processus de la valeur.. ce qui devrait résoudre la profondeur variable d'itération problème

OriginalL'auteur hangtwenty | 2011-10-12