Walking/iterating over a nested dictionary of arbitrary depth (the dictionary represents a directory tree)(遍历/迭代任意深度的嵌套字典(字典表示目录树))
问题描述
我几乎可以肯定有一个简单的解决方案,但我现在花了几个小时阅读和重新阅读同一组相关结果,这些结果并不能完全回答我的问题.
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.
这个问题的背景(包括在内,但可以跳过这个)
这是因为我希望用户能够从目录(以及任何子目录)中选择一组文件,不幸的是,Tkinter 在文件对话框中选择多个文件的默认功能在 Windows 7 上被破坏(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
ar.txt
Stories
Horror
scary.txt
Trash
otscary.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 框架.然后我希望通过解释哪些复选框是真或假来加载用户选择的各种文本文件.除了迭代字典没有固定深度之外,一切似乎都相当简单.
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)
这篇关于遍历/迭代任意深度的嵌套字典(字典表示目录树)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:遍历/迭代任意深度的嵌套字典(字典表示目录树)


基础教程推荐
- 如何让 python 脚本监听来自另一个脚本的输入 2022-01-01
- Python kivy 入口点 inflateRest2 无法定位 libpng16-16.dll 2022-01-01
- 筛选NumPy数组 2022-01-01
- Dask.array.套用_沿_轴:由于额外的元素([1]),使用dask.array的每一行作为另一个函数的输入失败 2022-01-01
- 线程时出现 msgbox 错误,GUI 块 2022-01-01
- 何时使用 os.name、sys.platform 或 platform.system? 2022-01-01
- 在 Python 中,如果我在一个“with"中返回.块,文件还会关闭吗? 2022-01-01
- 如何在海运重新绘制中自定义标题和y标签 2022-01-01
- 使用PyInstaller后在Windows中打开可执行文件时出错 2022-01-01
- 用于分类数据的跳跃记号标签 2022-01-01