Как преобразовать рекурсию в итерацию для этого кода, который преобразует объект дерева scipy в json?

Я пытаюсь преобразовать объект дерева Scipy (возвращенный из метода scipy to_tree) в json, чтобы я мог визуализировать дендрограмму в D3. В принципе, я пытаюсь сделать то же самое, что и:

дендрограмма scipy в json для визуализации дерева d3.js

Ответ, предложенный mdml, отлично работает, но в его ответе используется рекурсия в методе add_node. Когда данные большие, будет выброшено RuntimeError: maximum recursion depth exceeded.

Итак, я пытаюсь реализовать add_node, используя итерацию вместо рекурсии.

Следующий код - это то, что я пробовал, но он не дает мне правильного результата. После каждой итерации словарь «info» должен быть назначен списку «дочерние элементы», но проблема в том, что я не знаю, как перейти к самому внутреннему уровню дочерних элементов после каждой итерации. Как показано в ожидаемом результате ниже, внутри «детей» есть «дети» и так далее.

Итак, что мне делать, чтобы назначать «информацию» правильным «потомкам» после каждой итерации?

import pandas as pd 
import scipy.spatial
import scipy.cluster
import numpy as np
import json
import matplotlib.pyplot as plt
from functools import reduce

geneExp = {'genes' : ['a', 'b', 'c', 'd', 'e', 'f'],
       'exp1': [-2.2, 5.6, 0.9, -0.23, -3, 0.1],
       'exp2': [5.4, -0.5, 2.33, 3.1, 4.1, -3.2]
          }
df = pd.DataFrame( geneExp )
dataMatrix = np.array( df[['exp1', 'exp2']] )
distMat = scipy.spatial.distance.pdist( dataMatrix )

clusters = scipy.cluster.hierarchy.linkage(distMat, method='single')
T = scipy.cluster.hierarchy.to_tree( clusters , rd=False )
D = dict(children=[], name="Root1")
Nodes = [T]
while(1):
    for node in Nodes:
        if node.is_leaf()==True:
            info = dict(node_id=node.id,children=[])
            D['children'].append(info)
        else:
            if len(D['children'])>0:
                info = dict(node_id=node.id,children=[])
                D['children'].append(info)
                T1 = T.get_right()
                T2 = T.get_left()
                newNodes = [T1,T2]
                D = D['children'][0]   ### ???
                Nodes = newNodes
            else:
                info = dict(node_id=node.id,children=[])
                D['children'].append(info)
                T1 = T.get_right()
                T2 = T.get_left()
                newNodes = [T1,T2]
                D = D['children'][0]   ### ???
                Nodes = newNodes

Это ожидаемый результат.

{'children': [{'node_id': 10,
   'children': [{'node_id': 5, 'children': []},
    {'node_id': 9,
     'children': [{'node_id': 1, 'children': []},
      {'node_id': 8,
       'children': [{'node_id': 6,
         'children': [{'node_id': 2, 'children': []},
          {'node_id': 3, 'children': []}]},
        {'node_id': 7,
         'children': [{'node_id': 0, 'children': []},
          {'node_id': 4, 'children': []}]}]}]}]}],
 'name': 'Root1'}

person Patrick K    schedule 25.03.2019    source источник