[英]how to build a tree for ordered numbers?
我正在嘗試從輸入數字構建一棵樹(字典)。 我對樹的主要標准是一個級別中的所有節點都在同一范圍內。 (來自父母的一系列數據)我想你會從我的例子中得到想法-
請看例子
input_list=[1,2,3,4,5,
5.1,5.2,5.3,5.4,
6,7,8,8.1,8.2,8.21,
8.22,8.22,8.23,8.24,8.25,
8.3,8.4,8.5,
9,9.1,9.2,9.3,10,11,12]
expected_out_put={
0: [1,2,3,4,5,6,7,8,9,10,11,12],
5: [5.1,5.2,5.3,5.4],
8: [8.1,8.2,8.3,8.4,8.5],
8.2: [8.21,8.22,8.23,8.24,8.25],
9: [9.1,9.2,9.3],
}
我最初試圖建一棵樹。 這僅適用於數據 1-9,任何人都可以幫助我找到更好的解決方案這就是我嘗試的方法
class Section:
FIRST_TIME=False
def intialise(self):
self.rank=0
self.child_sections.clear()
self.next_value_diff=10000
parent=None
def __init__(self,**Kwargs):
self.rank = Kwargs['rank']
self.child_sections=[]
self.next_value_diff=0
def set_next_value_diff(self,value):
self.next_value_diff=value
def is_sibling(self,section_obj):
c_diff=abs(section_obj.rank-self.rank)
print('c_difference is '+str(c_diff)+"and prev differnec is"+str(self.next_value_diff))
if(self.next_value_diff>c_diff):
return False
return True
def add_child(self,section_obj):
prev_root=self
print("Self rank is"+str(self.rank))
print(len(self.child_sections))
print([i.rank for i in self.child_sections])
if(len(self.child_sections)>0):
prev_root=self.child_sections[-1]
c_diff=abs(section_obj.rank-prev_root.rank)
print("addred rank "+str(section_obj.rank)+" prev "+str(prev_root.rank)+"diffrenc "+str(c_diff))
section_obj.next_value_diff=c_diff
self.child_sections.append(section_obj)
print("added "+str(section_obj.rank)+"under "+str(self.rank)+"diffrenc "+str(c_diff))
return
data_stack=[1.0, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 2.1, 2.11, 2.12, 2.13, 2.14, 2.15, 2.16, 2.17, 2.18, 2.19, 2.2, 2.21, 2.22, 2.23, 2.24, 2.25, 2.26, 2.27, 2.28, 2.34, 2.35, 2.36, 2.37, 2.38, 2.39, 2.4, 2.42, 2.43, 2.44, 2.45, 2.46]
data_stack=[i*1000 for i in data_stack]
data_stack.reverse()
print(data_stack)
def create_root(parent):
print('Current parent is'+str(parent.rank))
global data_stack
while( (len(data_stack)>0) and (not parent.is_sibling(Section(rank=data_stack[-1])))):
rank_value=data_stack.pop()
print("poped value of "+str(rank_value))
section_obj=Section(rank=rank_value)
if(len(parent.child_sections)>0):
print("Found its "+str(parent.rank)+"has "+str(len(parent.child_sections))+" childrens")
#check any child exists
#sub_section is a sibling
child=parent.child_sections[-1]
print("checking simplinag "+str(section_obj.rank)+" : aginst child "+str(child.rank))
if child.is_sibling(section_obj):
print("yes he is simpler with "+str(rank_value)+" : aginst child "+str(child.rank))
parent.add_child(section_obj)
else:
print('not sibler')
nextparent=parent.child_sections.pop()
print('popped '+str(nextparent.rank))
print("Koids")
print([i.rank for i in nextparent.child_sections])
nextparent.add_child(section_obj)
print('recurent call happenmd')
parent.add_child(create_root(nextparent))
else:
print("No child at the time of"+str(rank_value))
parent.add_child(section_obj)
print("added to parent at the time of"+str(rank_value))
return parent
parent=Section(rank=0)
parent.intialise()
parent=create_root(parent)
print(parent.rank)
print([j.rank for j in parent.child_sections])
for k in parent.child_sections:
print('kids of'+str(k.rank))
print([m.rank for m in k.child_sections])
for m in k.child_sections:
print('kids of'+str(m.rank))
print([n.rank for n in m.child_sections])
for n in m.child_sections:
print('kids of'+str(n.rank))
print([s.rank for s in n.child_sections])
這是一個嘗試:
導入:我正在使用標准庫中的defaultdict
和groupby
:
from collections import defaultdict
from itertools import groupby
兩個輔助函數供以后使用:
def tuple_to_key(tup):
if len(tup) == 2:
return int(tup[0])
return float(f"{tup[0]}.{''.join(n for n in tup[1:-1])}")
def childs_to_float(childs):
return [float(f"{tup[0]}.{''.join(n for n in tup[1:])}") for tup in childs]
第 1 步:建立級別(假設input_list
已排序):
levels = defaultdict(list)
for tup in [(lst[0],) if len(lst) == 1 else (lst[0],) + tuple(lst[1])
for lst in [str(n).split('.') for n in input_list]]:
levels[len(tup)].append(tup)
結果如下:
{
1: [('1',), ('2',), ('3',), ('4',), ('5',), ('6',), ('7',), ('8',), ('9',), ('10',), ('11',), ('12',)],
2: [('5', '1'), ('5', '2'), ('5', '3'), ('5', '4'),
('8', '1'), ('8', '2'), ('8', '3'), ('8', '4'), ('8', '5'),
('9', '1'), ('9', '2'), ('9', '3')],
3: [('8', '2', '1'), ('8', '2', '2'), ('8', '2', '2'), ('8', '2', '3'), ('8', '2', '4'), ('8', '2', '5')]
}
第 2 步:查找父子關系:
output = {
parent: childs_to_float(childs)
for level in levels.keys() if level > 1
for parent, childs in groupby(levels[level], key=tuple_to_key)
}
if 1 in levels:
childs = [int(t[0]) for t in levels[1]]
output[min(childs) - 1] = childs
輸出:
{
0: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
5: [5.1, 5.2, 5.3, 5.4],
8: [8.1, 8.2, 8.3, 8.4, 8.5],
8.2: [8.21, 8.22, 8.22, 8.23, 8.24, 8.25],
9: [9.1, 9.2, 9.3]
}
我敢肯定里面有很多皺紋......
首先你得到鍵,它是零加上列表元素的唯一整數部分:
keys=set(map(lambda x: 0 if isinstance(x, int) else int(x), input_list))
那應該給你
{0, 5, 8, 9}
然后,您可以通過多種方式生成 int, list 的字典,例如:
{k: [y for y in input_list if (k==0 and isinstance(y, int)) or (k>0 and not isinstance(y, int) and int(y)==k)] for k in keys}
它是一個用你的鍵生成的字典,在里面,所有的列表只選擇那些符合要求的元素(整數或 key.decimal)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.