从文件层次结构创建嵌套字典
Creating Nested Dictionary from File hierarchy
我想知道是否有人可以指出正确的方向。我试图从文件路径列表创建一个嵌套字典,类似于下面的内容。这个列表会根据用户的输入而改变,所以我想它需要是递归的。关于从哪里开始的任何指示?
编辑: 此外,字典将被转换为 JSON 并用于使用 D3.js.
创建图表
fileDict = [
{
"name": "BaseLevel",
"children": [
{
"name": "/etc/",
"children": [
{
"name": "/etc/passwd",
},
{
"name": "/etc/group"
}
]
},
{
"name": "/root/",
"children": [
{
"name": "/root/test",
}
]
}
]
}
]
我能得到的最接近的例子是这个
records = ["base/images/graphs/one.png", "base/images/tikz/two.png",
"base/refs/images/three.png", "base/one.txt", "base/chapters/two.txt"]
recordsSplit = map(lambda x: x.split("/"), records)
for record in recordsSplit:
here = result
for item in record[:-1]:
if not item in here:
here[item] = {}
here = here[item]
if "###content###" not in here:
here["###content###"] = []
here["###content###"].append(record[-1])
print json.dumps(result, indent=4)
是否值得制作一个 class 而不是一个命令?写了一个应该做你想做的简短的
class FileSystem():
def __init__(filePath=None):
self.children = []
if files != None:
try:
self.name, child = files.split("/", 2)
self.children.append(FileSystem(filePath))
except (ValueError):
pass
def addChild(filePath):
self.children.append(FileSystem(filePath))
def getChildren():
return self.children
def printAllChildren():
print "Name: "+ self.name
print "{ Children:"
for child in self.children:
child.printAllChildren()
print "}"
然后您可以输入第一个路径并保存对它的引用,例如
myFileSystem = FileSystem("base/pictures/whatever.png")
这个 myFileSystem
将是您对“基本”级别的参考,使用它和它的方法您应该能够做您想做的事。
然后当您有第二条路径要添加时,您必须通过在 myFileSystem
上使用 getChildren()
找到要添加的正确节点,直到发现差异,然后使用 addChild()
将文件路径的其余部分添加到该节点。
然后使用 myFileSystem.printAllChildren()
将打印出整个文件系统。
--------编辑--------
对我写了一半的代码不太满意,喜欢挑战,所以这是一个易于使用的 class
class FileSystem():
def __init__(self,filePath=None):
self.children = []
if filePath != None:
try:
self.name, child = filePath.split("/", 1)
self.children.append(FileSystem(child))
except (ValueError):
self.name = filePath
def addChild(self, filePath):
try:
thisLevel, nextLevel = filePath.split("/", 1)
try:
if thisLevel == self.name:
thisLevel, nextLevel = nextLevel.split("/", 1)
except (ValueError):
self.children.append(FileSystem(nextLevel))
return
for child in self.children:
if thisLevel == child.name:
child.addChild(nextLevel)
return
self.children.append(FileSystem(nextLevel))
except (ValueError):
self.children.append(FileSystem(filePath))
def getChildren(self):
return self.children
def printAllChildren(self, depth = -1):
depth += 1
print "\t"*depth + "Name: "+ self.name
if len(self.children) > 0:
print "\t"*depth +"{ Children:"
for child in self.children:
child.printAllChildren(depth)
print "\t"*depth + "}"
records = ["base/images/graphs/one.png", "base/images/tikz/two.png",
"base/refs/images/three.png", "base/one.txt", "base/chapters/two.txt"]
myFiles = FileSystem(records[0])
for record in records[1:]:
myFiles.addChild(record)
myFiles.printAllChildren()
正如你在最后看到的那样,当我简单地执行 myFiles.addChild(record)
时,addChild 函数现在负责在树中找到正确的位置以使其进入。printAllChildren() 给出了正确的输出至少对于那些参数。
让我知道它是否有任何意义,就像我说的那样它没有经过全面测试,所以一些极端情况(例如试图添加另一个基地?)可能会使它变得奇怪。
EDIT2
class FileSystem():
def __init__(self,filePath=None):
self.children = []
if filePath != None:
try:
self.name, child = filePath.split("/", 1)
self.children.append(FileSystem(child))
except (ValueError):
self.name = filePath
def addChild(self, filePath):
try:
thisLevel, nextLevel = filePath.split("/", 1)
try:
if thisLevel == self.name:
thisLevel, nextLevel = nextLevel.split("/", 1)
except (ValueError):
self.children.append(FileSystem(nextLevel))
return
for child in self.children:
if thisLevel == child.name:
child.addChild(nextLevel)
return
self.children.append(FileSystem(nextLevel))
except (ValueError):
self.children.append(FileSystem(filePath))
def getChildren(self):
return self.children
def printAllChildren(self, depth = -1):
depth += 1
print "\t"*depth + "Name: "+ self.name
if len(self.children) > 0:
print "\t"*depth +"{ Children:"
for child in self.children:
child.printAllChildren(depth)
print "\t"*depth + "}"
def makeDict(self):
if len(self.children) > 0:
dictionary = {self.name:[]}
for child in self.children:
dictionary[self.name].append(child.makeDict())
return dictionary
else:
return self.name
records = ["base/images/graphs/one.png", "base/images/tikz/two.png",
"base/refs/images/three.png", "base/one.txt", "base/chapters/two.txt"]
myFiles = FileSystem(records[0])
for record in records[1:]:
myFiles.addChild(record)
print myFiles.makeDict()
当您有这样的文件时:
['testdata/hhohoho.mdf', 'testdata/dvojka/rerere.bdf', 'testdata/jedna/sss.txt']
你的输出结构如下:
Name: testdata
{ Children:
Name: hhohoho.mdf
Name: rerere.bdf
Name: sss.txt
}
你有一个错误:
self.children.append(FileSystem(nextLevel))
except (ValueError):
self.children.append(FileSystem(filePath))
解决方式如下:
self.children.append(FileSystem(thisLevel))
for child in self.children:
if thisLevel == child.name:
child.addChild(nextLevel)
return
Name: testdata
{ Children:
Name: hhohoho.mdf
Name: dvojka
{ Children:
Name: rerere.bdf
}
Name: jedna
{ Children:
Name: sss.txt
}
}
我想知道是否有人可以指出正确的方向。我试图从文件路径列表创建一个嵌套字典,类似于下面的内容。这个列表会根据用户的输入而改变,所以我想它需要是递归的。关于从哪里开始的任何指示?
编辑: 此外,字典将被转换为 JSON 并用于使用 D3.js.
创建图表fileDict = [
{
"name": "BaseLevel",
"children": [
{
"name": "/etc/",
"children": [
{
"name": "/etc/passwd",
},
{
"name": "/etc/group"
}
]
},
{
"name": "/root/",
"children": [
{
"name": "/root/test",
}
]
}
]
}
]
我能得到的最接近的例子是这个
records = ["base/images/graphs/one.png", "base/images/tikz/two.png",
"base/refs/images/three.png", "base/one.txt", "base/chapters/two.txt"]
recordsSplit = map(lambda x: x.split("/"), records)
for record in recordsSplit:
here = result
for item in record[:-1]:
if not item in here:
here[item] = {}
here = here[item]
if "###content###" not in here:
here["###content###"] = []
here["###content###"].append(record[-1])
print json.dumps(result, indent=4)
是否值得制作一个 class 而不是一个命令?写了一个应该做你想做的简短的
class FileSystem():
def __init__(filePath=None):
self.children = []
if files != None:
try:
self.name, child = files.split("/", 2)
self.children.append(FileSystem(filePath))
except (ValueError):
pass
def addChild(filePath):
self.children.append(FileSystem(filePath))
def getChildren():
return self.children
def printAllChildren():
print "Name: "+ self.name
print "{ Children:"
for child in self.children:
child.printAllChildren()
print "}"
然后您可以输入第一个路径并保存对它的引用,例如
myFileSystem = FileSystem("base/pictures/whatever.png")
这个 myFileSystem
将是您对“基本”级别的参考,使用它和它的方法您应该能够做您想做的事。
然后当您有第二条路径要添加时,您必须通过在 myFileSystem
上使用 getChildren()
找到要添加的正确节点,直到发现差异,然后使用 addChild()
将文件路径的其余部分添加到该节点。
然后使用 myFileSystem.printAllChildren()
将打印出整个文件系统。
--------编辑--------
对我写了一半的代码不太满意,喜欢挑战,所以这是一个易于使用的 class
class FileSystem():
def __init__(self,filePath=None):
self.children = []
if filePath != None:
try:
self.name, child = filePath.split("/", 1)
self.children.append(FileSystem(child))
except (ValueError):
self.name = filePath
def addChild(self, filePath):
try:
thisLevel, nextLevel = filePath.split("/", 1)
try:
if thisLevel == self.name:
thisLevel, nextLevel = nextLevel.split("/", 1)
except (ValueError):
self.children.append(FileSystem(nextLevel))
return
for child in self.children:
if thisLevel == child.name:
child.addChild(nextLevel)
return
self.children.append(FileSystem(nextLevel))
except (ValueError):
self.children.append(FileSystem(filePath))
def getChildren(self):
return self.children
def printAllChildren(self, depth = -1):
depth += 1
print "\t"*depth + "Name: "+ self.name
if len(self.children) > 0:
print "\t"*depth +"{ Children:"
for child in self.children:
child.printAllChildren(depth)
print "\t"*depth + "}"
records = ["base/images/graphs/one.png", "base/images/tikz/two.png",
"base/refs/images/three.png", "base/one.txt", "base/chapters/two.txt"]
myFiles = FileSystem(records[0])
for record in records[1:]:
myFiles.addChild(record)
myFiles.printAllChildren()
正如你在最后看到的那样,当我简单地执行 myFiles.addChild(record)
时,addChild 函数现在负责在树中找到正确的位置以使其进入。printAllChildren() 给出了正确的输出至少对于那些参数。
让我知道它是否有任何意义,就像我说的那样它没有经过全面测试,所以一些极端情况(例如试图添加另一个基地?)可能会使它变得奇怪。
EDIT2
class FileSystem():
def __init__(self,filePath=None):
self.children = []
if filePath != None:
try:
self.name, child = filePath.split("/", 1)
self.children.append(FileSystem(child))
except (ValueError):
self.name = filePath
def addChild(self, filePath):
try:
thisLevel, nextLevel = filePath.split("/", 1)
try:
if thisLevel == self.name:
thisLevel, nextLevel = nextLevel.split("/", 1)
except (ValueError):
self.children.append(FileSystem(nextLevel))
return
for child in self.children:
if thisLevel == child.name:
child.addChild(nextLevel)
return
self.children.append(FileSystem(nextLevel))
except (ValueError):
self.children.append(FileSystem(filePath))
def getChildren(self):
return self.children
def printAllChildren(self, depth = -1):
depth += 1
print "\t"*depth + "Name: "+ self.name
if len(self.children) > 0:
print "\t"*depth +"{ Children:"
for child in self.children:
child.printAllChildren(depth)
print "\t"*depth + "}"
def makeDict(self):
if len(self.children) > 0:
dictionary = {self.name:[]}
for child in self.children:
dictionary[self.name].append(child.makeDict())
return dictionary
else:
return self.name
records = ["base/images/graphs/one.png", "base/images/tikz/two.png",
"base/refs/images/three.png", "base/one.txt", "base/chapters/two.txt"]
myFiles = FileSystem(records[0])
for record in records[1:]:
myFiles.addChild(record)
print myFiles.makeDict()
当您有这样的文件时:
['testdata/hhohoho.mdf', 'testdata/dvojka/rerere.bdf', 'testdata/jedna/sss.txt']
你的输出结构如下:
Name: testdata
{ Children:
Name: hhohoho.mdf
Name: rerere.bdf
Name: sss.txt
}
你有一个错误:
self.children.append(FileSystem(nextLevel))
except (ValueError):
self.children.append(FileSystem(filePath))
解决方式如下:
self.children.append(FileSystem(thisLevel))
for child in self.children:
if thisLevel == child.name:
child.addChild(nextLevel)
return
Name: testdata
{ Children:
Name: hhohoho.mdf
Name: dvojka
{ Children:
Name: rerere.bdf
}
Name: jedna
{ Children:
Name: sss.txt
}
}