Учитывая двоичное дерево, выведите все пути от корня к листу с помощью scipy

#python #tree #scipy

#python #дерево #scipy

Вопрос:

Я использую hierarchy.to_tree from scipy, и мне интересно получить распечатку всех путей от корня к листу:

введите описание изображения здесь


10.8.3
10.8.5
10.2.2

 from scipy.cluster import hierarchy
a = hierarchy.to_tree(linkage_matrix)
  

Я попробовал

 linkage_matrix
[[2, 3, 0.06571365, 2], [0, 10, 0.07951425, 2], [5, 6, 0.09405724, 2], [11, 13, 0.10182075, 3], [1, 12, 0.12900146, 3], [14, 15, 0.13498948, 5], [8, 9, 0.16806049, 2], [7, 16, 0.1887918, 4], [17, 19, 0.2236683, 9], [18, 20, 0.29471335, 11], [4, 21, 0.45878, 12]]

from scipy.cluster import hierarchy
a = hierarchy.to_tree(linkage_matrix)

def parse_tree(tree, path):
    path = path
    if path ==[]:
        path.append(str(tree.get_id()))
    if tree.is_leaf() is False:
        left = tree.get_left()
        left_id = str(left.get_id())
        if left.is_leaf() is False:
            path.append(left_id)
            parse_tree(left, path)
            path.pop()
        else:
            parse_tree(left, path)
        right = tree.get_right()
        right_id = str(right.get_id())
        if right.is_leaf() is False:
            path.append(right_id)
        parse_tree(right, path)
    else:
        path.append(str(tree.get_id()))
        print(('.').join(path)) 
        path.pop()

parse_tree(a, [])
  

Но, очевидно, моя логика совершенно неверна, в частности, она ломается, когда левый узел не является leave (22.21.20.17.15.19.7 должно быть 22.21.20.19.7). Я ищу новые способы, которые я не рассматривал.

Для приведенного ниже примера дерева все пути от корня к листу:

Ответ №1:

Не глядя на ваш код, вы должны делать что-то вроде:

 print_paths(tree, seen):
    seen = seen
    seen.append(tree.value)
    if not tree.children:
        print(seen)
    else:
        map(print_paths, tree.children)
  

Теперь, увидев ваш код, попробуйте что-то вроде:

 def parse(tree, p):
    path = p[:]
    path.append(str(tree.get_id()))
    if tree.is_leaf():
        print('.'.join(path))
    else: 
        #Here I assume get_left() returns some falsey value for no left child
        left = tree.get_left()
        if left:
            parse(left, path)
        right = tree.get_right()
        if right:
            parse(right, path)
  

Комментарии:

1. Спасибо, что дали ему шанс, это разбивается аналогичным образом: >>> parse(a,[]) 22.4 22.4.21.18.8 22.4.21.18.8.9

2. Возможно, проблема в списке, переданном по ссылке. Я изменил path = path на path = p[:] where p аргумент

3. боже мой! Я думаю, это работает, что именно делает p[:] ? есть ли ссылка, которую я мог бы прочитать по этой теме?

4. Это мелкая копия списка. Это всего лишь фрагмент списка, который идет от начала до конца, но это означает, что он не имеет общей ссылки со списком itself.docs.python.org/3/tutorial/introduction.html#lists