Python 从数据列表构造树
假设我有一个如下的数字列表Python 从数据列表构造树,python,python-3.x,tree,hierarchical-clustering,Python,Python 3.x,Tree,Hierarchical Clustering,假设我有一个如下的数字列表 a = [1,23,5,72,3,5,15,7,78,1,5,77,23] 现在我需要根据这些数据构建一棵树 根据自定义函数par将数据集分为两部分。我们把这两部分叫做a0,a1 分别在a0和a1上应用函数par,得到a00、a01、a11、a12 重复此过程,直到结束节点上只剩下一个数字 对于每个终端节点,我们都有一个“二进制代码”,如“0010100”,其中0表示左侧,1表示每个特定步骤的右侧 我试图使用树类,如下所示,但一开始我就被卡住了 class Node
a = [1,23,5,72,3,5,15,7,78,1,5,77,23]
现在我需要根据这些数据构建一棵树
par
将数据集分为两部分。我们把这两部分叫做a0,a1par
,得到a00、a01、a11、a12class Node(input):
def __init__(self, data):
self.data = data
self.left = '*'
self.right = '*'
path为您提供二进制代码
Node.path为您提供二进制代码。不清楚内部节点将具有哪些值。这可能并不重要,但您可以始终指定数据数组中属于该特定子树的第一个值 “二进制代码”类似于从根到节点的导航路径。因此,对于您提供的数据,我们希望类似于此树:
值:1
路径:uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
/ \
价值:115
路径:_u0____1_______
/ \ / \
数值:1 72 15 1
路径:00 01 10 11__
/ \ / \ / \ / \
数值:123723157177
路径:000 001 010 011 100 101 110 111
/ \ / \ / \ / \ / \
数值:2353578157723
路径:0010 0011 0110 0111 1010 1011 1100 1101 1110 1111
您可以使用一个简单的节点
类,它可以存储值和路径:
class Node:
def __init__(self, value, path, left=None, right=None):
self.value = value
self.path = path
self.left = left
self.right = right
par
函数将执行如下操作:
def par(data):
i = len(data) // 2
return (data[:i], data[i:]) if i else ()
当只有一个数据元素时,if..else
运算符用于返回空列表。这在主要功能中很有用:
def maketree(data, path=""):
return Node(data[0], path, *(
maketree(part, path + str(i)) for i, part in enumerate(par(data))
))
这将枚举由par
返回的部分,并将这些部分传递给递归调用(如果返回了任何部分)。同时,递归调用获取一个路径字符串,该字符串用0或1(即枚举的索引)扩展
示例调用:
a = [1,23,5,72,3,5,15,7,78,1,5,77,23]
root = maketree(a)
# Output the properties of one particular node:
node = root.left.left.right.left
print("value: {}, path: {}".format(node.value, node.path))
# Outputs: "value: 23, path: 0010"
不清楚内部节点将具有哪些值。这可能并不重要,但您可以始终指定数据数组中属于该特定子树的第一个值 “二进制代码”类似于从根到节点的导航路径。因此,对于您提供的数据,我们希望类似于此树:
值:1
路径:uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
/ \
价值:115
路径:_u0____1_______
/ \ / \
数值:1 72 15 1
路径:00 01 10 11__
/ \ / \ / \ / \
数值:123723157177
路径:000 001 010 011 100 101 110 111
/ \ / \ / \ / \ / \
数值:2353578157723
路径:0010 0011 0110 0111 1010 1011 1100 1101 1110 1111
您可以使用一个简单的节点
类,它可以存储值和路径:
class Node:
def __init__(self, value, path, left=None, right=None):
self.value = value
self.path = path
self.left = left
self.right = right
par
函数将执行如下操作:
def par(data):
i = len(data) // 2
return (data[:i], data[i:]) if i else ()
当只有一个数据元素时,if..else
运算符用于返回空列表。这在主要功能中很有用:
def maketree(data, path=""):
return Node(data[0], path, *(
maketree(part, path + str(i)) for i, part in enumerate(par(data))
))
这将枚举由par
返回的部分,并将这些部分传递给递归调用(如果返回了任何部分)。同时,递归调用获取一个路径字符串,该字符串用0或1(即枚举的索引)扩展
示例调用:
a = [1,23,5,72,3,5,15,7,78,1,5,77,23]
root = maketree(a)
# Output the properties of one particular node:
node = root.left.left.right.left
print("value: {}, path: {}".format(node.value, node.path))
# Outputs: "value: 23, path: 0010"
你关注的是如何储存它。考虑一下如何进行分区。这棵树的根是什么?您的重点是如何存储它。考虑如何进行分区。此树的根是什么?非常有用的解决方案。顺便问一下,我需要为递归函数制作一个记忆包装器吗@TrincoMemorization在这里没有用处:只有当某个节点有可能被第二次访问,并且需要为其计算相同的信息时,它才会起作用。但事实并非如此。这是一个非常有用的解决方案。顺便问一下,我需要为递归函数制作一个记忆包装器吗@TrincoMemorization在这里没有用处:只有当某个节点有可能被第二次访问,并且需要为其计算相同的信息时,它才会起作用。但事实并非如此。