在任意深度的嵌套字典上行走/迭代(字典代表目录树) [英] Walking/iterating over a nested dictionary of arbitrary depth (the dictionary represents a directory tree)

查看:133
本文介绍了在任意深度的嵌套字典上行走/迭代(字典代表目录树)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我几乎可以肯定有一个简单的解决方案,但我现在花了几个小时阅读并重新阅读相同的相关结果,这些结果并没有完全解决我的问题。

I am almost certain there is a simple solution to this, but I have spent hours now reading and rereading the same set of related results that don't quite answer my problem.

此问题的上下文(包括完成但可以跳过此内容)

这是因为我想要一个用户能够从目录(以及任何子目录)中选择一组文件,不幸的是,在Windows 7上,Tkinter在文件对话框中选择多个文件的默认功能被破坏( http://bugs.python.org/issue8010

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).

因此我试图代表通过替代方法(仍然使用Tkinter)的目录结构:构建目录结构的传真,由标记和缩进复选框(在树中组织)组成。因此这样的目录:

Thus 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). Thus 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

使用我在ActiveState中找到的某个配方(见下文),可以轻松地从目录结构构建原始字典,但是我点击了当我试图迭代我留下的精美嵌套字典时,一堵墙。而且我认为我需要迭代它以便使用树的漂亮网格表示来填充Tkinter帧。然后我希望通过解释哪些复选框为true或false来加载用户选择的各种文本文件。一切看起来都相当容易,除了迭代字典而不用修复深度。

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. And I think I need to iterate over it in order to populate a Tkinter frame with a pretty gridded representation of the tree. Then I hope to load in the various text files selected by the user, by interpreting which checkboxes were true or false. Everything seems fairly easy except iterating over the dictionary without fixing the depth.

更抽象的术语

要制作这些嵌套词典,我使用的是ActiveState配方 - http://code.activestate.com/recipes/577879/ 。它实现了os.walk来制作如下字典:

To make these nested dictionaries I am using an ActiveState recipe -- http://code.activestate.com/recipes/577879/. It implements os.walk to make dictionaries such as this:

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

在此之后我感到难过。我在撰写本文时是一名Python新手

After which point I am stumped. I am a Python newbie at time of writing

根据spicavigo的回复改编的解决方案

#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

这会产生一些东西我认为将很容易修改为Tkinter表示:

This produces something that I think will be very easy to revise into a Tkinter representation:

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

谢谢,这个社区令人难以置信。

Thanks, this community is incredible.

推荐答案

是一个初步的代码。通过它并告诉我你在哪里遇到问题。

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': {
                'rickscott.txt' : None,
                'Trash' : {
                    'notscary.txt' : None,
                    },
                },
            'Cyberpunk' : None
            },
        'Poems' : {
            'doyoureadme.txt' : None
        }
    }
}

f(di=a)

这篇关于在任意深度的嵌套字典上行走/迭代(字典代表目录树)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆