下面是具有编程语言的树结构(使用节点实例构建)的节点类定义。现在如何使用节点类方法将分层节点数据树结构转换为python字典? 在底部查看所需的输出。
class Node(object):
def __init__(self, name, parent=None):
self._name = name
self._children = []
self._parent = parent
if parent is not None:
parent.addChild(self)
def addChild(self, child):
self._children.append(child)
def name(self):
return self._name
def setName(self, name):
self._name = name
def child(self, row):
return self._children[row]
def childCount(self):
return len(self._children)
def parent(self):
return self._parent
rootNode = nodeData.Node("books")
web_node = nodeData.Node("web", rootNode)
database_node = nodeData.Node("database", rootNode)
front_end_node = nodeData.Node("front-end", web_node)
back_end_node = nodeData.Node("back-end", web_node)
sql_node = nodeData.Node("sql", database_node)
nosql_node = nodeData.Node("nosql", database_node)
html_node = nodeData.Node("html", front_end_node)
css_node = nodeData.Node("css", front_end_node)
js_node = nodeData.Node("js", front_end_node)
php_node = nodeData.Node("php", back_end_node)
python_node = nodeData.Node("python", back_end_node)
mysql_node = nodeData.Node("mysql", sql_node)
postgresql_node = nodeData.Node("postgresql", sql_node)
mongodb_node = nodeData.Node("mongodb", nosql_node)
cassandra_node = nodeData.Node("cassandra", nosql_node)
html_book_one_node = nodeData.Node("the missing manual", html_node)
html_book_two_node = nodeData.Node("core html5 canvas", html_node)
css_book_one_node = nodeData.Node("css pocket reference", css_node)
css_book_two_node = nodeData.Node("css in depth", css_node)
js_book_one_node = nodeData.Node("you don't know js", js_node)
js_book_two_node = nodeData.Node("eloquent javascript", js_node)
php_book_one_node = nodeData.Node("modern php", php_node)
python_book_one_node = nodeData.Node("dive into python", python_node)
python_book_two_node = nodeData.Node("python for everybody", python_node)
python_book_three_node = nodeData.Node("Think Python", python_node)
mongodb_book_one_node = nodeData.Node("mongodb in action", mongodb_node)
mongodb_two_node = nodeData.Node("scaling mongodb", mongodb_node)
从节点树抽象到python字典
{“书籍”:{ “网络”:{ “前端”:{ “ html”:[“缺少的手册”,“核心html5画布”], “ css”:[“ css袖珍参考”,“ css深度”], “ js”:[“您不知道js”,“精通JavaScript”] }, “后端”:{ “ php”:[“现代php”], “ python”:[“深入python”,“适合所有人的python”, “思考Python”] } }, “数据库”:{ “ sql”:{ “ mysql”:[], “ postgresql”:[] }, “ nosql”:{ “ mongodb”:[“运行中的mongodb”,“扩展mongodb”], “ cassandra”:[] }}}}
class Node(object):
def __init__(self, name, parent=None):
self._name = name
self._children = []
self._parent = parent
if parent is not None:
parent.addChild(self)
def addChild(self, child):
self._children.append(child)
def name(self):
return self._name
def setName(self, name):
self._name = name
def child(self, row):
return self._children[row]
def childCount(self):
return len(self._children)
def parent(self):
return self._parent
class categoryNode(Node):
def __init__(self, name, parent=None):
super(categoryNode, self).__init__(name, parent)
class subCategoryNode(Node):
def __init__(self, name, parent=None):
super(subCategoryNode, self).__init__(name, parent)
class languageNode(Node):
def __init__(self, name, parent=None):
super(languageNode, self).__init__(name, parent)
class BookNode(Node):
def __init__(self, name, parent=None):
super(BookNode, self).__init__(name, parent)
rootNode = Node("books")
web_node = categoryNode("web", rootNode)
database_node = categoryNode("database", rootNode)
front_end_node = subCategoryNode("front-end", web_node)
back_end_node = subCategoryNode("back-end", web_node)
sql_node = subCategoryNode("sql", database_node)
nosql_node = subCategoryNode("nosql", database_node)
html_node = languageNode("html", front_end_node)
css_node = languageNode("css", front_end_node)
js_node = languageNode("js", front_end_node)
php_node = languageNode("php", back_end_node)
python_node = languageNode("python", back_end_node)
mysql_node = languageNode("mysql", sql_node)
postgresql_node = languageNode("postgresql", sql_node)
mongodb_node = languageNode("mongodb", nosql_node)
cassandra_node = languageNode("cassandra", nosql_node)
html_book_one_node = BookNode("the missing manual", html_node)
html_book_two_node = BookNode("core html5 canvas", html_node)
css_book_one_node = BookNode("css pocket reference", css_node)
css_book_two_node = BookNode("css in depth", css_node)
js_book_one_node = BookNode("you don't know js", js_node)
js_book_two_node = BookNode("eloquent javascript", js_node)
php_book_one_node = BookNode("modern php", php_node)
python_book_one_node = BookNode("dive into python", python_node)
python_book_two_node = BookNode("python for everybody", python_node)
python_book_three_node = BookNode("Think Python", python_node)
mongodb_book_one_node = BookNode("mongodb in action", mongodb_node)
mongodb_two_node = BookNode("scaling mongodb", mongodb_node)
答案 0 :(得分:1)
您有一个更大的问题,因为您使用的是同一类来表示书籍类别和实际书籍。鉴于此,不可能以编程方式确定mysql_node
和postgresql_node
是空类别而不是书籍。
要使此功能按您想要的方式工作,您将需要重新设计数据结构。我建议有一个用于子类别的列表_children
和一个用于书名(作为字符串)的列表_books
。请注意,此数据结构仍然有点模棱两可,因为没有子类别且没有书籍的节点可以呈现为空列表(即没有书籍的终端类别)或空字典(即没有子类别的非终端类别) ;我从这个问题推断出,空列表是理想的结果。
class Node:
def __init__(self, name, parent=None):
self._name = name
self._children = []
self._parent = parent
self._books = []
if parent is not None:
parent.addChild(self)
def name(self):
return self._name
def setName(self, name):
self._name = name
def parent(self):
return self._parent
def addChild(self, child):
if self._books:
raise ValueError('Node cannot have both sub-categories and books')
self._children.append(child)
def child(self, row):
return self._children[row]
def childCount(self):
return len(self._children)
def addBook(self, book):
if self._children:
raise ValueError('Node cannot have both sub-categories and books')
self._books.append(book)
def book(self, row):
return self._books[row]
def bookCount(self):
return len(self._books)
rootNode = Node("books")
web_node = Node("web", rootNode)
database_node = Node("database", rootNode)
front_end_node = Node("front-end", web_node)
back_end_node = Node("back-end", web_node)
sql_node = Node("sql", database_node)
nosql_node = Node("nosql", database_node)
html_node = Node("html", front_end_node)
css_node = Node("css", front_end_node)
js_node = Node("js", front_end_node)
php_node = Node("php", back_end_node)
python_node = Node("python", back_end_node)
mysql_node = Node("mysql", sql_node)
postgresql_node = Node("postgresql", sql_node)
mongodb_node = Node("mongodb", nosql_node)
cassandra_node = Node("cassandra", nosql_node)
html_node.addBook("the missing manual")
html_node.addBook("core html5 canvas")
css_node.addBook("css pocket reference")
css_node.addBook("css in depth")
js_node.addBook("you don't know js")
js_node.addBook("eloquent javascript")
php_node.addBook("modern php")
python_node.addBook("dive into python")
python_node.addBook("python for everybody")
python_node.addBook("Think Python")
mongodb_node.addBook("mongodb in action")
mongodb_node.addBook("scaling mongodb")
def node_to_dict(node):
def helper(n):
if n.childCount() > 0:
return { c.name(): helper(c) for c in n._children }
else:
return list(n._books)
return { node.name(): helper(node) }
node_to_dict(rootNode)
的结果会==
达到您的预期输出。
答案 1 :(得分:0)
简单的递归函数:
def to_dict(node):
if isinstance(node, nodeData.Node):
return {node._name:to_dict(node._children)}
if all(isinstance(i, nodeData.Node) for i in node):
return (lambda x:x if all(x.values()) else list(x))({i._name:to_dict(i._children) for i in node})
return node
print(to_dict(rootNode))
输出:
{'books': {'web': {'front-end': {'html': ['the missing manual', 'core html5 canvas'], 'css': ['css pocket reference', 'css in depth'], 'js': ["you don't know js", 'eloquent javascript']}, 'back-end': {'php': ['modern php'], 'python': ['dive into python', 'python for everybody', 'Think Python']}}, 'database': {'sql': ['mysql', 'postgresql'], 'nosql': ['mongodb', 'cassandra']}}}