Python: преобразовать список списков в иерархический словарь. - PullRequest
0 голосов
/ 17 июня 2020

У меня есть данные по секвенированию генов, как показано ниже:

data = [{'sequence': 'gene1__gene2__gene3', 'occurrence': 10},
        {'sequence': 'gene2__gene3', 'occurrence': 5},
        {'sequence': 'gene2', 'occurrence': 2},
        {'sequence': 'gene4', 'occurrence': 4}
       ]

Я хочу преобразовать это в следующую (древовидную) dictionary структуру данных, где любой подпуть сообщает мне о совместном появлении количество этого набора генов:

tree_dict = {
        'gene1': {'occurrence': 10, 'self': 0, 'children': {'gene2': {'occurrence': 10, 'self': 0, 'children': {'gene3': {'occurrence': 10, 'self': 10, 'children': {}}}},
                                                            'gene3': {'occurrence': 10, 'self': 0, 'children': {'gene2': {'occurrence': 10, 'self': 10, 'children': {}}}},
                                                           }
                 },
        'gene2': {'occurrence': 17, 'self': 2, 'children': {'gene1': {'occurrence': 10, 'self': 0, 'children': {'gene3': {'occurrence': 10, 'self': 10, 'children': {}}}},
                                                            'gene3': {'occurrence': 15, 'self': 5, 'children': {'gene1': {'occurrence': 10, 'self': 10, 'children': {}}}},
                                                           }
                 },
        'gene3': {'occurrence': 15, 'self': 0, 'children': {'gene1': {'occurrence': 10, 'self': 0, 'children': {'gene2': {'occurrence': 10, 'self': 10, 'children': {}}}},
                                                            'gene2': {'occurrence': 15, 'self': 5, 'children': {'gene1': {'occurrence': 10, 'self': 10, 'children': {}}}},
                                                           }
                 },
        'gene4': {'occurrence': 4, 'self': 4, 'children': {}}
       }

В tree_dict выше:

  • self относится к появлению только узлов в (под) пути. Например: gene3 никогда не существует сам по себе и поэтому имеет self значение 0; в то время как gene2 существует сам по себе 2 раз и, таким образом, имеет значение self 2.
  • occurrence относится к появлению узлов в (под) пути как в виде подстрок, так и в целом.

Код, который я пробовал?
Я пробовал использовать итеративные подходы к отказу, когда я знаю, что решение этой проблемы должно быть рекурсивной функцией. Что-то похожее на этот вопрос: Как преобразовать список в иерархию dict . Но мне не удалось продвинуться в этом направлении.

1 Ответ

1 голос
/ 17 июня 2020

Попробуйте следующее:

data = [{'sequence': 'gene1__gene2__gene3', 'occurrence': 10},
        {'sequence': 'gene2__gene3', 'occurrence': 5},
        {'sequence': 'gene2', 'occurrence': 2},
        {'sequence': 'gene4', 'occurrence': 4}]

tree_dict = {}

def generate_tree(sequence, occurrence, curr_dict):
    gene_list = sequence.split('__')
    for gene in gene_list:
        if gene in curr_dict:
            curr_dict[gene]['occurrence'] += occurrence
        else:
            curr_dict[gene] = {'occurrence': occurrence, 'self': 0, 'children': {}}
        updated_list = gene_list.copy()
        updated_list.remove(gene)
        updated_sequence = '__'.join(updated_list)
        if updated_sequence != '':
            generate_tree(updated_sequence, occurrence, curr_dict[gene]['children'])
        else:
            curr_dict[gene]['self'] += occurrence

for item in data:
    generate_tree(item['sequence'], item['occurrence'], tree_dict)

print(tree_dict)
...