dri*_*her 7 python iteration tree recursion dictionary
我几乎可以肯定有一个简单的解决方案,但我现在花了几个小时阅读和重读相同的一组相关结果,这些结果并没有完全解决我的问题.
这个问题的背景(包括完成但可以跳过这个)
出现这种情况是因为我希望用户能够从目录(以及任何子目录)中选择一组文件,不幸的是,Tkinter在文件对话框中选择多个文件的默认功能在Windows 7上被破坏(http:/ /bugs.python.org/issue8010).
因此,我试图通过另一种方法(仍然使用Tkinter)来表示目录结构:构建目录结构的传真,由标记和缩进复选框(在树中组织)组成.因此像这样的目录:
\SomeRootDirectory
\foo.txt
\bar.txt
\Stories
\Horror
\scary.txt
\Trash
\notscary.txt
\Cyberpunk
\Poems
\doyoureadme.txt
Run Code Online (Sandbox Code Playgroud)
看起来像这样(其中#代表一个checkbutton):
SomeRootDirectory
# foo.txt
# bar.txt
Stories
Horror
# scary.txt
Trash
# notscary.txt
Cyberpunk
Poems
# doyoureadme.txt
Run Code Online (Sandbox Code Playgroud)
使用我在ActiveState中找到的某个配方(见下文),可以很容易地从目录结构构建原始字典,但是当我尝试迭代我留下的精美嵌套字典时,我遇到了问题.而且我认为我需要迭代它以便使用树的漂亮网格表示来填充Tkinter帧.然后我希望通过解释哪些复选框为true或false来加载用户选择的各种文本文件.除了在不修复深度的情况下迭代字典外,一切看起来都相当容易.
用更抽象的术语来说
要制作这些嵌套的词典,我使用的是ActiveState配方 - http://code.activestate.com/recipes/577879/.它实现了os.walk来制作如下的字典:
a={
'SomeRootDirectory': {
'foo.txt': None,
'bar.txt': None,
'Stories': {
'Horror': {
'horror.txt' : None,
'Trash' : {
'notscary.txt' : None,
},
},
'Cyberpunk' : None
},
'Poems' : {
'doyoureadme.txt' : None
}
}
}
Run Code Online (Sandbox Code Playgroud)
在此之后我感到难过.在撰写本文时,我是一名Python新手
解决方案改编自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
Run Code Online (Sandbox Code Playgroud)
这会产生一些我认为很容易修改为Tkinter表示的东西:
SomeRootDirectory
/===Poems
|---|---doyoureadme.txt
/===Stories
/===/===Horror
|---|---|---rickscott.txt
/===/===/===Trash
|---|---|---|---notscary.txt
/===/===Cyberpunk
|---foo.txt
|---bar.txt
Run Code Online (Sandbox Code Playgroud)
谢谢,这个社区令人难以置信.
这是一个打印所有文件名的函数.它遍历字典中的所有键,如果它们映射到非字典的东西(在您的情况下,文件名),我们打印出名称.否则,我们在映射到的字典上调用该函数.
def print_all_files(directory):
for filename in directory.keys():
if not isinstance(directory[filename], dict):
print filename
else:
print_all_files(directory[filename])
Run Code Online (Sandbox Code Playgroud)
因此,可以修改此代码以执行任何操作,但这只是一个示例,说明如何通过使用递归来避免修复深度.
要理解的关键是每次调用print_all_files时,它都不知道它在树中的深度.它只是查看那里的文件,并打印名称.如果有直升机,它就会在它们上运行.
这是初步代码。仔细检查并告诉我你在哪里遇到问题。
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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10719 次 |
| 最近记录: |